gpt4 book ai didi

c++ - 无法在 C++17 之前的模式下使用 static constexpr 进行编译

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:21:38 25 4
gpt4 key购买 nike

为什么以下最小示例不能用 c++11c++14 编译,而是用 c++17 编译> 和 c++2a?

#include <iostream>
#include <limits>
#include <vector>

// works:
// static constexpr int VALUE_LIMIT_A = std::numeric_limits<int>::max();

class Classy {
// does not work in c++11 (constexpr introduced) nor c++14:
// works if c++17 or newer:
static constexpr int VALUE_LIMIT_A = std::numeric_limits<int>::max();
int VALUE_LIMIT_B = std::numeric_limits<int>::max();

public:
explicit Classy();
std::vector<int> classy;
};

Classy::Classy() {
// does not work:
classy.resize(3, VALUE_LIMIT_A);

// works:
// classy.resize(3, std::numeric_limits<int>::max());

// works:
// std::cout << VALUE_LIMIT_A;

// works:
// classy.resize(3, VALUE_LIMIT_B);
}

// required in c++11 and c++14
// constexpr int Classy::VALUE_LIMIT_A;

int main() {
Classy classy{};

for (const auto& elem : classy.classy) {
std::cout << elem << ",";
}
std::cout << "\n";
}

这是 c++11 的输出:

$ g++ -std=c++11 main.cpp && ./a.out
/tmp/ccon7pPo.o: In function `Classy::Classy()':
main.cpp:(.text+0x31): undefined reference to `Classy::VALUE_LIMIT_A'
collect2: error: ld returned 1 exit status

这是 c++17 的输出:

$ g++ -std=c++17 main.cpp && ./a.out
2147483647,2147483647,2147483647,

最佳答案

因为从 C++17 开始,constexpr 的定义 static data member在命名空间范围内不再需要。

If a const non-inline (since C++17) static data member or a constexpr static data member (since C++11) is odr-used, a definition at namespace scope is still required, but it cannot have an initializer. This definition is deprecated for constexpr data members (since C++17).

struct X {
static const int n = 1;
static constexpr int m = 4;
};
const int *p = &X::n, *q = &X::m; // X::n and X::m are odr-used
const int X::n; // … so a definition is necessary
constexpr int X::m; // … (except for X::m in C++17)

If a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope. This redeclaration without an initializer (formerly required as shown above) is still permitted, but is deprecated. (since C++17)

注意 std::vector::resize通过引用获取第二个参数;这导致 VALUE_LIMIT_Aodr-used对于 classy.resize(3, VALUE_LIMIT_A);

关于c++ - 无法在 C++17 之前的模式下使用 static constexpr 进行编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56520629/

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