有一些已知的方法来操纵整数文字的类型
0L; // long
3U; // unsigned integer
1LL; // long long
Run Code Online (Sandbox Code Playgroud)
我需要的是一种初始化整数文字的方法std::size_t
.我以为这样做
2U; // unsigned int
Run Code Online (Sandbox Code Playgroud)
就足够了,但是在调用函数模板时仍然会遇到编译器错误,该函数模板需要两个相同整数类型的参数(没有匹配的函数可以调用func(unsigned int, size_t
)
我知道/验证显式cast(static_cast<std::size_t>(1)
)第一个参数解决了问题,但我在问是否有更漂亮的解决方案
编辑
该功能有签名
template <class T> const T& func(const T& a, const T& b);
Run Code Online (Sandbox Code Playgroud)
EDIT2
我不知道这个问题是否是"责备",但我很高兴地宣布这是即将到来的(在评论中提到这个问题的@malat)
Pot*_*ter 53
没有这样的标准设施.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, "" );
Run Code Online (Sandbox Code Playgroud)
的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 }
都是病态的.
大括号和parens看起来相似,但在初始化临时工时它们是安全的极端.大括号比文字运算符更安全,因为与函数不同,它们可以区分编译时值.
Rei*_*ica 28
没有专用的后缀std::size_t
.在C++ 11中,您可以为它创建一个用户定义的文字,但是:
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");
Run Code Online (Sandbox Code Playgroud)
从C ++ 23开始,你可以使用uz
或UZ
字面size_t
。
auto size = 42uz;
static_assert(std::is_same_v<decltype(size), std::size_t>);
Run Code Online (Sandbox Code Playgroud)
根据功能,您也可以这样做,并且可能会发现它更干净:
auto result = func<size_t>(1, some_var);
Run Code Online (Sandbox Code Playgroud)
例如,我已经这样做了std::max
:
auto result = std::max<size_t>(0, std::min<size_t>(index, vec.size()-1));
Run Code Online (Sandbox Code Playgroud)
通过显式指定模板实例化,转换可以是隐式的。但是,请注意,这是一个强制转换,因此容易出现Potatoswatter 的大括号初始化所没有的错误。
归档时间: |
|
查看次数: |
14278 次 |
最近记录: |