初始化程序列表中的非常量表达式不能从类型'int'缩小为'unsigned long long'

anonuser01
int main(int argc, char const *argv[])
{
   int x =  4;
   int y = 2;
   const int cell = x/y;
   auto a = std::bitset<20>{cell}; //fails
   auto b = std::bitset<20>(cell); //works
}

为什么std::bitset在这里不允许我使用花括号进行构建,而是使用括号构建?如果cellconstexpr,则两者都将编译。

编译错误:

test.cpp:21:29: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned long long' in initializer list [-Wc++11-narrowing]
   auto a = std::bitset<20>{x*y}; //fails
                            ^~~
test.cpp:21:29: note: insert an explicit cast to silence this issue
   auto a = std::bitset<20>{x*y}; //fails
                            ^~~
                            static_cast<unsigned long long>( )
1 error generated.
f9c69e9781fa194211448473495534

失败的行使用列表初始化语法:

auto a = std::bitset<20>{cell}; //fails

该语法在C ++ 17标准的11.6.4节中定义相关部分:

对象或类型引用的列表初始化T定义如下:

...

(3.7)否则,如果T是类类型,则考虑构造函数。列举了适用的构造函数,并通过重载分辨率(16.3,16.3.1.7)选择了最佳的构造函数。如果需要变窄的转换(请参见下文)以转换任何参数,则程序格式错误。

...

缩小转换是隐式转换

...

(7.4)从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非source是一个常量表达式,其整数提升后的值将适合目标类型

这使我们对发生的事情有了更好的了解:

// Works, no narrowing check, implicit conversion.
std::bitset<20> a(2);
std::bitset<20> b(-1);
std::bitset<20> c(cell); 

// Works, 2 can be converted without narrowing
std::bitset<20> d{2};

// Fails, -1 cannot be converted without narrowing
std::bitset<20> e{-1};

// Fails, compiler does not understand cell can be converted without narrowing
std::bitset<20> f{cell};

在您的程序中,编译器无法理解这cell是一个常量表达式。它检查可用的构造函数,以std::bitset查看是否必须从转换intunsigned long long它认为这int可能是负面的,因此我们的转换范围越来越窄。

我们可以通过制作比强大的cella来解决此问题仅意味着不应更改该值意味着该值在编译时可用:constexprconstconstconstexpr

  constexpr int x = 4;
  constexpr int y = 2;
  constexpr int cell = x / y;

  auto a = std::bitset<20>{cell}; // works

您现在可以问为什么列表初始化不允许缩小转换范围。我无法完全回答。我的理解是,通常认为隐式缩小是不希望的,因为它可能会产生意想不到的后果,并且出于这个原因而将其排除在外。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

错误:在编译`gcc`时,将'-1'的转换范围从'int'缩小为'long unsigned int'[-Wnarrowing]

从unsigned long long转换为unsigned int

如何使用printf格式化unsigned long long int?

NSLogs中的unsigned int和unsigned long Xcode警告

在C中为静态const double分配一个静态const unsigned long long int变量

错误:{}中的'18446744069414584320ull'从'long long unsigned int'转换为'int'的转换变窄[-Wnarrowing]

如何在Entity Framework中使用unsigned int / long类型?

C#中unsigned long int的等效项是什么?

for循环运行long long int,但不运行unsigned long long int

在 CMSIS 中,为什么位域位置是 'unsigned int' 而掩码基数是 'unsigned long int'?

C ++ unsigned int和unsigned long int之间的区别

类型unsigned long long int是否足以用于1-10 ^ 9范围?

关于char或int或short或long或unsigned的警告

unsigned long long int在循环中的奇怪行为

无法将boost :: lambda :: ...转换为long long unsigned int

将BYTE数组转换为unsigned long long int

Python中的Long Long Int

什么是java中的unsigned long

如何初始化C语言中的unsigned long long

为什么“自动 x = -2147483648;” 将 x 设置为 unsigned long 类型而不是 int 类型?(VS2017)

unsigned int到unsigned long长定义好了吗?

不能将超过 32 位的字符移位为 unsigned long long

在C ++中,“ long”,“ long long”,“ long int”和“ long long int”有什么区别?

BigDecimal中的NumberFormatException为int或long(java)

为什么(c ++)从long long unsigned int转换为long double然后返回0

如何将 unsigned long long int 转换为 unsigned char*?

解决了“警告:从'int'转换为'long unsigned int'的问题”

long long转换为unsigned long的问题

缩小从“ int”(常量表达式)到“ unsigned int”的转换-MSVC vs gcc vs clang