架构x86_64的未定义符号链接constexpr std :: array
Undefined symbols for architecture x86_64 linking constexpr std::array
我在链接对象文件时会遇到错误:
#include <cstdint>
#include <array>
enum SystemType : uint8_t { AC, DC, HCP, EFF };
template<SystemType TYPE> struct System;
template<>
struct System<AC> {
public:
static constexpr size_t number_of_sockets = 2;
static constexpr std::array<size_t, number_of_sockets> object_per_socket { { 12, 6 } };
};
我正在将其如下所示将数据分配为向量。
terminal->no_obj_per_system.assign(
Sytem<AC>::object_per_socket.begin(),
Sytem<AC>::object_per_socket.end());
我在Mac OS上使用clang。
在C 14和更早之前,静态数据成员如果它们是 odr-使用的,则必须在一个翻译单元中具有一个隔离的定义;此规则仍然适用于constexpr
成员。
这个问题包含一个示例,其中包含来自C 14标准的参考。
如果没有提供课外定义,并且该变量是 odr使用的,则不需要诊断,这解释了为什么有些人没有得到汇编错误。为了安全起见,您应该提供一个定义,即使在变量不使用 odr使用的情况下,也没有损害。。
定义看起来像(不在标题文件中(:
constexpr std::array<size_t, System<AC>::number_of_sockets> System<AC>::object_per_socket;
在C 17中,有一个新功能"内联变量",它允许在具有与内联函数相似的语义的标题文件中定义变量,即,您可以在翻译单元中具有多个匹配的定义,并且编译器/链接器将根据需要选择一个。constexpr
变量将是隐式inline
,因此您的原始代码在C 17中是正确的。GCC和Clang的最新版本应使用-std=c++1z
标志接受代码。
相关文章:
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 为什么std::isnan 不是 constexpr?
- constexpr上下文中std::initializer_list的验证
- constexpr begin of a std::array
- 是否已经有一个 constexpr std::bit_cast 与 g++ 一起使用
- C++ standard: ODR and constexpr std::string_view
- 是否可以以编程方式初始化 constexpr std::array 成员
- 架构x86_64的未定义符号链接constexpr std :: array
- 带有constexpr std :: string_view vs用std :: string实例化枚举的枚举
- 是否可以将constexpr std :: array变成std :: integer_sequence
- constexpr std :: initializer_list的编译时验证
- 将constexpr std ::对阵列置换
- 静态初始化包含功能指针的对象的constexpr std ::数组
- 初始化一个constexpr std ::数组,其大小的n维std ::数组
- constexpr std ::可选的可能实现
- Constructing a constexpr std::weak_ptr
- 是否可以在编译时使用`constexpr std::initializer_list`,但不能使用ODR
- constexpr std::array with static_assert
- 这个代码怎么可能是constexpr?(std::chrono)
- 不能创建constexpr std::vector