Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

c++ - Initialize integer literal to std::size_t

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 way to initialize an integer literal to std::size_t. I supposed that doing

2U; // unsigned int

would be enough, but I still get a compiler error when calling a function template that expects two arguments of the same integral type (no matching function to call for func(unsigned int, size_t)

I know/verified that explicitly casting ( static_cast<std::size_t>(1) ) the first argument solves the problem but I'm asking if there's a prettier solution

EDIT

the function has a signature

template <class T> const T& func(const T& a, const T& b);

EDIT2

I don't know if this question is to "blame" but I'm happy to announce that this is upcoming (cudos @malat for mentioning this in the comments)

question from:https://stackoverflow.com/questions/22346369/initialize-integer-literal-to-stdsize-t

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...