将整数字符串初始化为std :: size_t [英] Initialize integer literal to std::size_t

查看:201
本文介绍了将整数字符串初始化为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 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)

解决方案

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.

这篇关于将整数字符串初始化为std :: size_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆