c++ - 体系结构 x86_64 链接 constexpr std::array 的 undefined symbol

标签 c++ c++14 constexpr

我在链接目标文件时遇到错误:

#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 } }; 
};

我如下使用它来将数据分配到 vector 中。

terminal->no_obj_per_system.assign(
            Sytem<AC>::object_per_socket.begin(),
            Sytem<AC>::object_per_socket.end());

我在 mac 操作系统上使用 clang。

最佳答案

在 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 变量将隐式内联,因此您的原始代码在 C++17 中是正确的。最新版本的 gcc 和 clang 应该接受带有 -std=c++1z 标志的代码。

关于c++ - 体系结构 x86_64 链接 constexpr std::array 的 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44401526/

相关文章:

c++ - 如何在 Valgrind 上设置分析的开始和结束

c++ - 从哪里获得 Explorerframe.lib?

c++ - 与尼康自己的转换器相比,Libraw 使我的图像太亮

c++ - constexpr const 与 constexpr 变量?

c++11 - Arduino 1.6.9/1.610 构建失败,出现 "' constexprint' 未命名类型”

c++ - 在头文件中包含指令?

c++ - 散列多态类型的正确方法

c++ - C++14 中泛型 Lambda 中的静态自动变量

带有可选参数的 C++ 构造函数

c++ - 使用constexpr返回函数值C++的模板函数调用