c++ - 如何定义一个 constexpr 构造数组,该数组在多个翻译单元上只有一个实例?

标签 c++ c++14 constexpr

我正在 constexpr 类内生成一个 constexpr std::array,但我只想要该类在其所在的所有项目中的一个实例使用过。

我最初将其设为全局变量,但后来我发现,如果我在多个翻译单元中迭代数组,这些全局变量就会重复。然后,我尝试使用 constexpr 函数,但在这样的函数内部不能有 static 。我使用的是 c++14,因此无法使用内联 constexpr 变量。 extern constexpr 变量没有意义,因为如果将声明与定义分开,那么如何在编译时而不是运行时处理 constexpr 值当只需要一件元素时如何处理?

还有其他选择吗?

编辑:参见 https://godbolt.org/z/5PcboYov4

请记住,我没有定义常规变量。我正在定义一个 constexpr 变量。区别很重要。它在非 constexprconstexpr 上下文中使用。

最佳答案

变量模板具有外部链接,即使它们是 const 限定的:

template<typename = void>
constexpr std::array my_array{/*...*/};

// use my_array<> to access the array.

但这只是从DR 2387开始,我想这也应该适用于 C++14,尽管它直到 2019 年才得到解决。

如果编译器没有实现它,那么您可以显式添加extern。据我所知,这是允许的,并且声明仍然是一个定义,因为它有一个初始值设定项。因为它是一个模板,所以多个定义不存在 ODR 违规:

template<typename = void>
extern constexpr std::array my_array{/*...*/};

// use my_array<> to access the array.

出于某种原因,我忘记了使用静态数据成员的最明显的解决方法:

struct my_array_wrapper {
    static constexpr std::array</*...*/> my_array{/*...*/};
};

// in one translation unit
constexpr std::array</*...*/> my_array_wrapper::my_array;

然后可以使用my_array_wrapper::my_array。如果仅在 C++17 之前使用 ODR 数组,则需要翻译单元中的定义。具有外部链接的类中的静态数据成员也具有外部链接,无论它们是否是 const 限定的。

关于c++ - 如何定义一个 constexpr 构造数组,该数组在多个翻译单元上只有一个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75011467/

相关文章:

c++ - 数组声明中的常量表达式

c++ - 指向 C++ 类成员函数的指针作为全局函数的参数?

c++ - 将 Visual C++ 控制台输出复制(不重定向)到文本文件,同时仍在控制台窗口中查看输出

c++ - 为什么 vector<std::function> 的元素可以绑定(bind)到 C++ 中的不同函数签名?

C++自动生成带有用户声明的析构函数的移动构造函数?

c++ - 对程序的编译时属性进行基准测试

c++ - 为什么在 constexpr 函数中不允许 goto?

c++ - clang:自定义属性在 AST 中不可见

c++ - 如何像 boost::unwrap_reference 一样打开 std::reference_wrapper

c++ - 这是使用 c_str 异常未定义行为吗?