类中的静态constexpr类中的链接问题

类中的静态constexpr类中的链接问题

本文介绍了类中的静态constexpr类中的链接问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在类中定义 static constexpr 。我知道这个问题:,方法3现在正常工作。

I'm trying to create static constexprs defined inside the class. I know about this question: static constexpr member of same type as class being defined, and method 3 works fine now.

但是,我有一个链接器的问题。它报告重复的符号,可能是因为 const constexpr 重新定义。有办法做到这一点吗?我使用xcode 7。

However, I have a problem with the linker. It reports of duplicate symbols, probably because of the const to constexpr redefinition. Is there a way to accomplish this? I am using xcode 7.

我想要的代码是:

class foo{
    int _x;
    constexpr foo(int x) : _x(x) {}
public:
    static const foo a, b, c;
    constexpr int x() const { return _x; }
};

constexpr foo foo::a = foo(1), foo::b = foo(2), foo::c = foo(1);

在多个位置包含此文件会导致链接器错误,说明

Including this file in more than one place causes a linker error stating

3 duplicate symbols for architecture x86_64

推荐答案

我知道这是问题,因为如果我只包括它一旦工作正常。 static const变量,然后将它们定义为constexpr。由于constexpr的静态成员必须是完整的,它不能在类本身的范围内。您的代码应如下所示:

Well, you define first three static const variables and then you defines them as constexpr. Since constexpr static member must be complete, it cannot be in the scope of the class itself. Your code should look like this:

class foo {
int _x;
public:
    constexpr foo(int x) : _x(x) {}
    constexpr int x() const { return _x; }
};

constexpr foo a = foo{1}, b = foo{2}, c = foo{1};

如果你仍然希望foo作为静态成员,你可以做这个小技巧:

If you still desire to have foo as a static member you can do this little trick:

class foo {
int _x;
    constexpr foo(int x) : _x(x) {}
    struct constants;
public:
    constexpr int x() const { return _x; }
};

struct foo::constants {
    constexpr static foo a = foo{1}, b = foo{2}, c = foo{1};
};

现在为什么会出现链接错误?

这个小规则称为单一定义规则,它规定了所有编译单元中可以有任意数量的声明,但是有一个定义。根据您的问题中包含的代码段,它看起来像是在标题中定义静态成员。如果有两个编译单元包括你的头,你打破规则。用我上面的代码示例,你不应该有这个错误,但另一个,而不是:没有定义。 constexpr值可能在编译时使用,但在运行时将不可用。为此,您必须在.cpp文件中声明这一点:

There's this little rule called the One Definition Rule, which states that there can be any number of declaration but one definition across all compilation units. By your code snippet you included in your question, it look like you are defining your static member in your header. If there's two compilation unit including your header, you break the rule. With my code example above you should not have this error anymore, but another one instead: there is no definition. the constexpr value might be used at compile time, but won't be usable at runtime. To do this, you must declare this in a .cpp file:

#include "foo.h"

constexpr foo foo::constants::a;
constexpr foo foo::constants::b;
constexpr foo foo::constants::c;

现在您的三个静态变量已正确声明和定义。

Now your three static variables are correctly declared and defined.

这篇关于类中的静态constexpr类中的链接问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 08:55