ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 类内部类的静态constexpr链接问题

2019-08-29 19:07:19  阅读:165  来源: 互联网

标签:c c11 clang


我正在尝试创建在类中定义的静态constexprs.我知道这个问题:static constexpr member of same type as class being defined,方法3现在工作正常.

但是,我的链接器有问题.它报告重复符号,可能是因为const到constexpr重新定义.有没有办法实现这个目标?我正在使用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);

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

3 duplicate symbols for architecture x86_64

我知道这是问题所在,因为如果我只在它工作正常后才包含它.

解决方法:

好吧,你定义前三个静态const变量,然后你将它们定义为constexpr.由于constexpr静态成员必须是完整的,因此它不能在类本身的范围内.您的代码应如下所示:

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作为静态成员,你可以做这个小技巧:

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};
};

如果您使用的是C 14之前,请遵循此操作.在C 17中,所有constexpr静态数据成员都是隐式内联的.

现在为什么链接错误?

这个小规则称为一个定义规则,它规定在所有编译单元中可以有任意数量的声明但只有一个定义.通过您在问题中包含的代码段,您似乎在标题中定义了静态成员.如果有两个包含标题的编译单元,则会违反规则.使用上面的代码示例,您不应再有此错误,而是另一个错误:没有定义. constexpr值可能在编译时使用,但在运行时不可用.为此,您必须在.cpp文件中声明:

#include "foo.h"

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

现在正确声明和定义了三个静态变量.

标签:c,c11,clang
来源: https://codeday.me/bug/20190829/1762623.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有