尝试初始化静态地图。从其他问题我收集到它必须在头文件之外完成,并且在c ++ 11中可以通过统一初始化来完成。但是当我尝试使用另一个静态成员时,我遇到了问题:
foo.h:
#include <map>
class TestSuite {
static constexpr int x = 3;
static std::map<int, int> v;
};
Foo.cpp中:
#include "foo.h"
std::map<int, int> TestSuite::v = {{x, 5}};
int main() {
TestSuite t;
}
然后我收到错误
In function `__static_initialization_and_destruction_0(int, int)':
foo.cpp:(.text+0x4b): undefined reference to `TestSuite::x'
collect2: error: ld returned 1 exit status
答案 0 :(得分:4)
我无法使用GCC 6.1.0重现此问题。但是,只要您尝试将引用绑定到未定义的constexpr
变量,就可以重现它,这可能是您的std::map
构造函数所做的:
struct Foo {
static constexpr int i = 42;
};
int main() {
auto const &p = Foo::i; // undefined reference to `Foo::i'
}
这是因为绑定引用是i
的{{3}},这需要在链接时存在唯一的定义。
有一个简单的解决方法适用于大多数此类情况,即应用一元+
:
struct Foo {
static constexpr int i = 42;
};
int main() {
auto const &p = +Foo::i; // OK!
}
应用+
并非ODR使用i
,因为只需要其值,而不是其身份。然后引用绑定到+
返回的临时值,而不是i
。
答案 1 :(得分:3)
您还需要定义TestSuite::x
。把它放在你的cpp文件中:
const int TestSuite::x;
答案 2 :(得分:1)
另一种解决方案。
将static
成员变量更改为static
成员函数。
class TestSuite {
static constexpr int getX() { return 3;}
static std::map<int, int> v;
};
和
std::map<int, int> TestSuite::v = {{getX(), 5}};