定义constexpr静态数据成员

时间:2018-04-30 22:26:57

标签: c++ class c++11 static constexpr

所以,我知道在C ++中静态成员可以在类中初始化,如果它们是const文字类型,如下所示

class test{
public:
        static constexpr int stc = 1;
private:
        int a = 0;
        int b = 0;
        int c = 0;
};

并且可以使用静态constexpr变量stc,编译器可以直接替换成员的值,即

int main () {int array[test::stc];}  

但是,如果在不能由编译器直接替换值的上下文中使用:

int main() { const int &cs = test::stc; } 

然后编译器(clang)生成错误

c++ -std=c++11 -pedantic    t.cpp   -o t
Undefined symbols for architecture x86_64:
  "test::stc", referenced from:
      _main in t-a8ee2a.o
ld: symbol(s) not found for architecture x86_64

除非静态成员在类之外定义,如下所示:

constexpr int test::stc;

为什么会这样?

3 个答案:

答案 0 :(得分:2)

int main() { const int &cs = test::stc; } 

中使用

test::stc

int main () {int array[test::stc];}  

不是。

the C++11 Standard中的以下示例支持上述想法。

struct S { static const int x = 0; };
const int &f(const int &r);  
int n = b ? (1, S::x)    // S​::​x is not odr-used here
          : f(S::x);     // S​::​x is odr-used here, so a definition is required

从实际角度来看,cs将是无效的引用,除非test::stc具有地址。另一方面,array只需要test::stc的值,可以在编译时进行评估。 array不需要test::stc的地址作为有效对象。

一个使用过的对象必须在程序中只定义一次。

答案 1 :(得分:1)

static constexpr int stc = 1; // declares the static var

constexpr int test::stc; // defines the static var

有关详细说明,请查看以下链接

http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

答案 2 :(得分:0)

C ++ 17 inline变量

在C ++ 17中,如果您还将静态成员也标记为inline,那么我认为您可以自由使用odr或在编译单元中具有多个定义,例如:

#include <iostream>

class MyClass {
    public:
        inline static constexpr int i = 42;
};


int main() {
    const int &cs = MyClass::i;
    std::cout << cs << std::endl;
    std::cout << &MyClass::i << std::endl;
}

更多信息,请访问:How do inline variables work?