类型化的静态constexpr字段以g ++

时间:2016-12-30 13:40:04

标签: c++ c++11

我今天正在测试这段代码:

#include <iostream>

struct Literal {
    constexpr operator int() const { return 0; }
};

struct Class {
    constexpr static const Literal field0 = Literal();
};

int main(void) {
    std::cout << "Class::field0: " << Class::field0 << std::endl;
    return 0;
}

它编译时没有错误(G ++ 6.2.1),但不幸的是,生成可执行文件时出现链接错误:

/tmp/ccao6eTy.o: In function `main':
test-constexpr-static-field.cpp:(.text+0xa): undefined reference to `Class::field0'
collect2: error: ld returned 1 exit status
[Finished in 0.3s with exit code 1]

阅读this page我看到了这个解释:

  

如果声明了LiteralType的静态数据成员constexpr,   必须使用初始化程序初始化每个表达式   是一个常量表达式,就在类定义(...)中。

然后我去了definition of what is a LiteralType,我看到了:

  

文字类型是以下任何一种:

     
      
  • 可能具有以下所有属性的cv限定类类型:      
        
    • 有一个简单的析构函数,
    •   
    •   
    • 聚合类型,
    •   
    • 具有至少一个constexpr(可能是模板)构造函数的类型,该构造函数不是复制或移动构造函数,
    •   
    • 闭包类型(自C ++ 17起)
    •   
  •   
  • 所有非静态数据成员和基类都是非易失性文字类型。
  •   

Literal是否与LiteralType不一致?在我看来,它有一个简单的构造函数,甚至没有内部状态来避免文字类型上的聚合类型或非静态字段的任何麻烦问题。

但是考虑到它确实符合(主要是因为程序编译没有错误),为什么链接时错误?这可能是一个G ++错误吗?

1 个答案:

答案 0 :(得分:0)

好吧,显然我需要在课外添加定义

工作示例:

#include <iostream>

struct Literal {
    constexpr Literal() = default;
    constexpr operator int() const { return 0; }
};

struct Class {
    constexpr static const Literal field0 = Literal();
};

// This is needed to avoid undefined reference errors
// This is a definition. Very strange.
constexpr const Literal Class::field0;

int main(void) {
    std::cout << "Class::field0: " << Class::field0 << std::endl;
    return 0;
}

来源:https://stackoverflow.com/a/8016853/3962396