Initialize integer literal to std::size_t

前端 未结 3 1669
醉梦人生
醉梦人生 2021-01-03 18:18

There are known ways to manipulate the type of an integer literal

0L;  // long
3U;  // unsigned integer
1LL; // long long

What I need is a

相关标签:
3条回答
  • 2021-01-03 18:23

    Depending on the function, you may also be able to do this and may find it cleaner:

    auto result = func<size_t>(1, some_var);
    

    For example, I've done this with std::max:

    auto result = std::max<size_t>(0, std::min<size_t>(index, vec.size()-1));
    

    By explicitly specifying the template instantiation, the casts can be implicit. However, do note that this is a cast, so is susceptible to errors which Potatoswatter's brace initialization isn't.

    0 讨论(0)
  • 2021-01-03 18:29

    There is no such standard facility. C99 and C++11 implementations do have such macros in <stdint.h>/<cstdint>. But even there, the macros are only defined for the stdint.h types, which do not include size_t.

    You could define a user-defined literal operator:

    constexpr std::size_t operator "" _z ( unsigned long long n )
        { return n; }
    
    auto sz = 5_z;
    static_assert( std::is_same< decltype( sz ), std::size_t >::value, "" );
    

    The constexpr is necessary to use it in array bounds int arr[ 23_z ] or case 9_z: labels.

    Most would probably consider the lack of macros to be an advantage :) .


    Cuteness aside, the best way is to use brace initialization: std::size_t{ 42 }. This is not equivalent to std::size_t( 42 ) which is like a nasty C cast — presumably what you were avoiding with static_cast. Quite the opposite: the braces require that the value inside is exactly representable in the targeted type. So, char{ 300 } and std::size_t{ -1 } are both ill-formed.

    Braces and parens look similar, but they're polar opposites in safety when initializing temporaries. Braces are safer than the literal operator could ever be, since unlike a function they can discriminate compile-time values.

    0 讨论(0)
  • 2021-01-03 18:32

    There is no dedicated suffix for std::size_t. In C++11, you could create a user-defined literal for it, though:

    std::size_t operator "" _sz (unsigned long long int x)
    {
      return x;
    }
    
    // Usage:
    
    auto s = 1024_sz;
    
    static_assert(std::is_same<decltype(s), std::size_t>::value, "He's wrong");
    

    Live example

    0 讨论(0)
提交回复
热议问题