arm*_*007 2 c++ constexpr c++11
我想用make_tuple()在constexpr.它适用于全球范围.但它会为static constexpr类成员生成链接错误.
#include <iostream>
#include <tuple>
using namespace std;
class A
{
public:
static constexpr auto z = make_tuple(5, 3.0);
};
constexpr auto tp = make_tuple(6, 3.2);
int main()
{
cout << get<0>(tp) << " " << get<1>(tp) << endl; // OK
cout << get<0>(A::z) << " " << get<1>(A::z) << endl; // error: (.text+0x5a): undefined reference to `A::z'
// (.text+0x67): undefined reference to `A::z'
}
Run Code Online (Sandbox Code Playgroud)
我已经检查了这里 make_tuple本身不是constexpr在c++11.我猜这不是问题.如果是,它将生成编译错误而不是链接错误.
我试图constexpr像这个答案所建议的那样定义类外的类
class A
{
public:
static constexpr tuple<int, double> z;
};
constexpr tuple<int, double> A::z = make_tuple(5, 3.0);
Run Code Online (Sandbox Code Playgroud)
但是,它会产生几个编译错误.这使得sanse根据constexpr使用静态函数初始化静态成员的答案
make_tuple在static constexpr班级成员中使用的正确方法是什么?
编译:
g++ 4.8.4和clang 3.4同-std=c++11
在C++ 11/14中,如果使用ODR ,则static constexpr必须在某处定义变量(ODR使用的意思是"以需要它的方式使用它具有标识".例如,采用真实的引用或指向它们的指针.ODR here表示"一个定义规则",而ODR使用的意思是"在某种意义上使用它需要它只有一个定义",我将其缩写为"具有一个身份").
constexpr tuple<int, double> A::z;
Run Code Online (Sandbox Code Playgroud)
我们已经定义了它存在的位置.这需要只有一个编译单元.
在C++ 17中,inline添加了变量,我相信constexpr变量是内联隐式的.我不是C++ 17的专家,但是它编译并运行在没有定义的C++ 1z模式中,所以我的解释似乎至少是正确的一半.
(inline变量,就像inline函数一样,最终在编译器需要的地方创建定义. inline函数通常通过在每个目标文件中定义一个带有特殊注释的定义来实现,当有人获取它的地址时,然后在链接时丢弃重复项.每个人都指最后一个站着.我不知道inline变量是否倾向于以相同的方式实现.)
如果你想在C++ 11中解决这个问题,而不必在.cpp带有硬编码模板参数的文件中放置一些东西,可以更改z为constexpr函数并在想要使用它时调用它.
正如SergyA所提到的,ODR在这里被触发,因为它get返回对所讨论的元组中的字段的引用,并且该引用意味着字段必须存在,因此整个元组必须存在.
从理论上讲,value_get按价值返回的精心设计可以避免使用ODR,但这取决于实现,tuple因为它无法调用get.
| 归档时间: |
|
| 查看次数: |
549 次 |
| 最近记录: |