我在链接目标文件时遇到错误:
#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。
答案 0 :(得分:5)
在C ++ 14及更早版本中,如果静态数据成员 odr-used ,则必须在一个翻译单元中具有类外定义;此规则仍适用于constexpr
成员。
This question包含一个带有C ++ 14标准参考的示例。
如果没有提供类外定义,并且该变量是 odr-used ,那么它是错误的,不需要诊断,这解释了为什么有些人没有得到编译错误。为了安全起见,你应该提供一个定义,即使在变量不是 odr-used 的情况下,这样做也没有坏处。
定义看起来像(不在头文件中):
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
标志的代码。