Kyl*_*and 1 c++ one-definition-rule constexpr c++11
在下面的独立程序中,我for原本期望循环在编译时展开,甚至完全计算,Foo::MyNumbers在链接时不必要:
struct Foo
{
constexpr static auto MyNumbers =
{
3,
28,
200,
};
};
constexpr int getSum(void)
{
auto sum = 0;
for (constexpr auto i : Foo::MyNumbers)
{
sum += i;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
然而,即使有-O3,既clang++3.7(从源代码编译之前的3.7版本)和g++5.1给出一个类似的错误; clang说read of non-constexpr variable '__begin' is not allowed in a constant expression,虽然g++说the value of '__for_begin' is not usable in a constant expression.
我真的不能想到任何可以在编译时有用std::initizlizer_list而没有迭代它的任何东西,事实上这个begin()方法确实标记constexpr为C++ 14.那么有什么东西可以用一个constexpr std::initializer_list不需要ODR定义的东西来实现吗?
注意:我正在编译-std=c++14两个编译器,但我意识到它们可能不完全符合 - 即使我使用的版本是相当新的.我有兴趣知道更多最新版本是否允许上述代码.
编辑:与ChrisBeck讨论后改变了我的例子和我的分析; 请参阅他的回答下的讨论,以及编辑此问题的历史记录.
编辑2:根据TC的建议,我constexpr从for循环中移除,离开for (auto i : Foo::MyNumbers).这导致undefined reference to 'Foo::MyNumbers'与GCC和Clang 的链接错误.
ODR不依赖于优化选项.ODR是标准的一部分.
该标准未参考优化选项.相反,不同的编译器应该按照他们认为合适的方式构成不同的优化方案,并且具有很大的余地.ODR应该确保符合规范的代码将链接到所有符合要求的编译器.(谢谢C++标准委员会!)
所以,请不要忘记循环展开以及链接时的含义.对于ODR而言,唯一重要的是是否使用了ODR.
我无法想到在编译时可以有效完成的任何事情......除了循环展开和初始化对象
由于C++ 14 std::initializer_list是文字类型.因此,您可以在编译时计算中轻松使用它.std::initializer_list在某些代码库中,使用a初始化具有constexpr构造函数的对象非常常见.
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |