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

时间:2014-03-12 08:54:33

标签: c++

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

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))第一个参数解决了问题,但我问的是否有更漂亮的解决方案

修改

该功能有签名

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

EDIT2

我不知道这个问题是否归咎于&#34;责备&#34;但是我很高兴地宣布this is upcoming(在评论中提到这个问题,@ malat)

4 个答案:

答案 0 :(得分:50)

没有这样的标准设施。 C99和C ++ 11实现在<stdint.h> / <cstdint>中确实有这样的宏。但即使在那里,宏也只为stdint.h类型定义,不包括size_t

could定义了一个用户定义的文字运算符:

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, "" );

在数组边界constexprint 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 :(得分: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");

Live example

答案 2 :(得分:7)

从 C++23 开始,您可以对 uz 使用 UZsize_t 字面量。

auto size = 42uz;
static_assert(std::is_same_v<decltype(size), std::size_t>);

纸:P0330R8
cppreference:Integer literals

答案 3 :(得分:4)

根据功能的不同,您也可以这样做,并且可能会发现它更清洁:

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

例如,我已使用std::max

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

通过显式指定模板实例化,可以隐式转换。 然而,请注意这是演员表,因此容易出错,Potatoswatter's brace initialization不是