将整数字符串初始化为std :: size_t [英] Initialize integer literal to std::size_t
问题描述
有一些已知的方法来处理整型文字的类型。
0L; // long
3U; // unsigned integer
1LL; // long long
我需要一种方法来初始化一个整数文字到 std :: size_t
。我想这样做
2U; // unsigned int
就足够了,但是当调用函数模板时,期望两个同样整数类型的参数(没有匹配的函数调用 func(unsigned int,size_t
)
我知道/验证显式转换( static_cast< std :: size_t>(1)
)第一个参数解决了问题,但我问如果有一个更漂亮的解决方案
EDIT
该函数有签名
template< class T> const T& func(const T& a,const T& b);
pre>
EDIT2
我不知道这个问题是责怪,但我很高兴地宣布,这个即将到来(cudos @malat在评论中提到这一点)解决方案没有这样的标准设施。 C99和C ++ 11实现确实在
< stdint.h>
/< cstdint>
中有这样的宏。但是即使是这样,宏只是为stdint.h
类型定义的,它不包括size_t
。您可以定义用户定义的文字运算符:
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,);
constexpr
数组边界int arr [23_z]
或case 9_z:
标签。
大多数人可能会认为缺少宏是一个优势:)。
方法是使用大括号初始化:
std :: size_t {42}
。这不等同于std :: size_t(42)
这就像一个讨厌的C类型 - 可能是你正在通过static_cast
。恰恰相反:大括号要求内部的值在目标类型中是完全可表示的。因此,char {300}
和std :: size_t {-1}
都是错误的。
括号和括号看起来相似,但是在初始化临时值时,它们是安全的极性对立面。大括号比字面量操作符更安全,因为与函数不同,它们可以区分编译时值。
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 doing2U; // 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 solutionEDIT
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)
解决方案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 thestdint.h
types, which do not includesize_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 boundsint arr[ 23_z ]
orcase 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 tostd::size_t( 42 )
which is like a nasty C cast — presumably what you were avoiding withstatic_cast
. Quite the opposite: the braces require that the value inside is exactly representable in the targeted type. So,char{ 300 }
andstd::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.
这篇关于将整数字符串初始化为std :: size_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!