gpt4 book ai didi

c++ - 非常量表达式不能从初始化列表中的类型 'int' 缩小到 'unsigned long long'

转载 作者:行者123 更新时间:2023-12-05 06:49:12 25 4
gpt4 key购买 nike

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.

最佳答案

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

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

此语法在 Section 11.6.4 中定义C++17 标准。相关部分:

List-initialization of an object or reference of type T is defined as follows:

...

(3.7) Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (16.3, 16.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.

...

A narrowing conversion is an implicit conversion

...

(7.4) from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

这让我们更好地理解正在发生的事情:

// 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 的可用构造函数,发现它必须从 int 转换为 unsigned long long。它认为 int 可能为负数,因此我们进行了收缩转换。

我们可以通过使 cell 成为 constexpr 来解决这个问题,它比 const 更强大。 const 仅表示该值不应更改,constexpr 表示该值在编译时可用:

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

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

您现在可能会问为什么列表初始化不允许缩小转换。我不能完全回答这个问题。我的理解是,隐式缩小通常被认为是不可取的,因为它可能会产生意想不到的后果,因此它被排除在外。

关于c++ - 非常量表达式不能从初始化列表中的类型 'int' 缩小到 'unsigned long long',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66621955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com