c++ - 模板变量的显式特化

标签 c++ templates c++14 linker-errors explicit-specialization

类似于this question关于模板类的静态 const 类成员的显式特化,以及 this question关于模板类的显式特化,但我的问题是变量模板的显式特化。

我的MCVE:

//my_templated_literal.h
#pragma once

template <typename T>
constexpr T val;
//my_specialised_literal.h
#pragma once

#include "my_templated_literal.h"

template <>
constexpr int val<int> = 2;
//my_specialised_literal.cc
#include "my_specialised_literal.h"
//main.cc
#include "my_specialised_literal.h"

int main() {}

编译命令:$CXX -std=c++14 my_specialized_literal.cc main.cc 它可以编译并且似乎在我尝试过的几乎每个编译器版本上都能按预期工作,但会在 clang-9 中给出链接器错误:

/tmp/main-ec49c7.o:(.rodata+0x0): multiple definition of `val'

/tmp/my_specialised_literal-521691.o:(.rodata+0x0): first defined here

这是大多数编译器版本默认接受的 ODR 违规,还是 clang-9 在某些方面是错误的?如果是前者,我知道如果我可以使用 C++17,我可以通过使特化内联来修复它,但是什么是针对该问题的 C++14 修复呢?

最佳答案

我想我已经解决了这个问题:

Is this an ODR violation silently accepted by most compiler versions?

据我了解,是的。根据storage class specifiers cppreference 页面中,模板变量应该具有外部链接,即使它是 constexpr,这意味着在翻译单元中具有多个定义是 ODR 违规。根据defect report该页面底部的链接显示,“当前的实现似乎为 const 限定变量模板的特化提供了内部链接”,标准委员会认为这不是他们想要的行为。

What is a C++14 fix for the problem?

好像没有。

关于c++ - 模板变量的显式特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58495283/

相关文章:

C++ 访问静态 constexpr 数组

c++ - 使用 SHAppBarMessage 移动任务栏

c++ - 使用 `extern template` 防止模板类的隐式实例化

Django 模板 : smartly slice the HTML content

c++ - 我可以使用模板在 QString 和 std::string 之间进行自动转换吗?

c++ - 将自动分配的 std::vector 转换为动态分配的 std::vector 而无需复制开销

c++ - 使用文字为模板类型赋值

c++ - 采用左值操作数的运算符的结果是一个左值,表示该左值操作数?

c++ - 以下哪些模仿 C++17 之前的折叠表达式的技术被认为是惯用的?

c++ - 这是 std::quote 错误的行为吗?