c++ - 使用静态成员初始化静态映射

标签 c++ c++11 dictionary static

正在尝试初始化静态 map 。从其他问题我收集到它必须在头文件之外完成,并且在 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

最佳答案

我无法使用 GCC 6.1.0 重现此问题。但是,只要您尝试将引用绑定(bind)到您尚未定义的 constexpr 变量,它就可以重现,这可能是您的 std::map 构造函数所做的:

struct Foo {
    static constexpr int i = 42;
};

int main() {
    auto const &p = Foo::i; // undefined reference to `Foo::i'
}

这是因为绑定(bind)引用是一个 ODR-use i,这需要在链接时存在唯一定义。

在大多数此类情况下,有一个简单的解决方法,那就是应用一元 +:

struct Foo {
    static constexpr int i = 42;
};

int main() {
    auto const &p = +Foo::i; // OK!
}

应用 + 不会 ODR 使用 i,因为只需要它的值,而不需要它的标识。然后引用绑定(bind)到 + 返回的临时值,而不是 i

关于c++ - 使用静态成员初始化静态映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37791387/

相关文章:

c++ - 如果分离的 std::thread 使用超出范围的对象是否安全?

javascript - Reactjs - 从 event.target 检索属性

c++ - 为什么 C++ 隐式转换有效,但显式转换会抛出错误(具体示例)?

c++ - 如何解决这个图像处理问题——分类

c++ - Clion如何部署项目?

c++ - 将 Dijkstra 算法与 unordered_map 图结合使用

java - 在 map 中,按一个字段排序并按另一个字段删除元素?

c++ - cygwin cmake 找不到 boost 库

C++运算符重载,我自己的字符串类

c++ - 具有显式构造函数的类是否需要 piecewise_construct in emplace?