emplace_back会导致静态 constexpr 成员上出现链接错误



为什么emplace_back引用需要定义的成员?emplace_back(integer literal)emplace_back(static constexpr integer member)有什么区别?

如果我切换到 C++17,它可以很好地编译。我发现在 C++17 中,静态 constexpr 数据成员是隐式内联的。这是否意味着编译器隐式地为它们创建定义?

示例代码:

class base {
int n;
public:
base(int n):n(n) {}
};
struct base_trait {
static constexpr int n = 1;
};
int main(void) {
vector<base> v;
v.emplace_back(1);  // ok
v.emplace_back(base_trait::n);  // link error with -std=c++14, ok with -std=c++17
return 0;
}

正如你所说,emplace_back通过引用来获取参数,所以传递base_trait::n会导致它被 odr 使用。

如果一个对象的值被读取(除非它是编译时常量(或写入,它的地址被获取,或者引用绑定到它,则对象被 ODR 使用;

在C++17之前,这意味着这里需要定义base_trait::n。但是自 C++17 以来,行为发生了变化,对于 constexpr 静态数据成员,不再需要类外定义。

如果使用 constnon-inline (since C++17)静态数据成员or a constexpr static data member (since C++11),则仍然需要在命名空间范围内进行定义,但它不能具有初始值设定项。This definition is deprecated for constexpr data members (since C++17).

静态数据成员可以内联声明。内联静态数据成员可以在类定义中定义,并且可以指定初始值设定项。它不需要类外定义。(自C++17起(

相关内容

  • 没有找到相关文章

最新更新