emplace_back导致静态constexpr成员上的链接错误 [英] emplace_back causes link error on static constexpr member

查看:135
本文介绍了emplace_back导致静态constexpr成员上的链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why does emplace_back take a reference of the member that requires a definition? What is the difference between emplace_back(integer literal) and emplace_back(static constexpr integer member)?

如果我切换到C ++ 17,它可以正常编译.我发现在C ++ 17中,静态constexpr数据成员隐式地

If I switch to C++17, it compiles fine. I found that in C++17 static constexpr data members are implicitly inlined. Does it mean the compiler implicitly creates a definition for them?

示例代码:

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使其成为

As you said, emplace_back takes arguments by reference, so passing base_trait::n causes it to be odr-used.

如果对象的值被读取(除非它是一个编译时间常数)或被写入,其地址被获取或对其绑定了一个引用,则该对象将被使用.

an object is odr-used if its value is read (unless it is a compile time constant) or written, its address is taken, or a reference is bound to it;

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

Before C++17, that means the definiton of base_trait::n is required here. But since C++17 the behavior changed, for constexpr static data member the out-of-class definition is not needed again.

如果odr使用了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).

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).

可以将静态数据成员声明为内联.内联静态数据成员可以在类定义中定义,并且可以指定初始化程序.它不需要类外定义. (自C ++ 17起)

A static data member may be declared inline. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition. (since C++17)

这篇关于emplace_back导致静态constexpr成员上的链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆