将整数文字初始化为std :: size_t

Nik*_*iou 29 c++

有一些已知的方法来操纵整数文字的类型

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看起来相似,但在初始化临时工时它们是安全的极端.大括号比文字运算符更安全,因为与函数不同,它们可以区分编译时值.

  • +1你应该建议使用`z`而不是`_z`来包含库.它会简化`for(auto i = 0z; i <v.size(); ++ i)`之类的东西 (3认同)

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)

实例

  • +1表示对语言中最少使用的运算符的正确用法. (3认同)
  • +1 但我更喜欢 `z` 而不是 `sz` 以符合 C99 printf 的 `%z` (2认同)

Syn*_*nck 9

从C ++ 23开始,你可以使用uzUZ字面size_t

auto size = 42uz;
static_assert(std::is_same_v<decltype(size), std::size_t>);
Run Code Online (Sandbox Code Playgroud)

论文:P0330R8
cppreference:整数文字


Nei*_*aft 7

根据功能,您也可以这样做,并且可能会发现它更干净:

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 的大括号初始化所没有的错误。