为什么emplace_back
会引用需要定义的成员? emplace_back(integer literal)
和emplace_back(static constexpr integer member)
之间有什么区别?
如果我切换到C ++ 17,它编译得很好。我发现在C ++ 17中,静态constexpr数据成员是隐式的inlined。这是否意味着编译器隐式为它们创建定义?
示例代码:
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;
}
答案 0 :(得分:9)
正如您所说,emplace_back
通过引用获取参数,因此传递base_trait::n
会使其成为odr-used。
如果一个对象的值被读取(除非它是一个编译时常量)或写入,它的地址被采用,或者一个引用被绑定,它就会被使用;
在C ++ 17之前,这意味着此处需要base_trait::n
的定义。但是,自从C ++ 17以来,行为发生了变化,对于constexpr static data member,不再需要类外定义。
如果使用const
non-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起)