模板变量的显式特化

Explicit specialization of template variable

类似于 about explicit specialisation of static const class members of a template class, and 关于模板的显式特化 class,但我的问题是变量模板的显式特化。

我的 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_specialised_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,我可以通过进行专业化 inline 来修复它,但是什么是 C++14 修复问题?

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

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

据我了解,是的。根据该页面底部的 storage class specifiers cppreference page, the template variable should have external linkage, even though it's constexpr, which means having multiple definitions in a translation unit is an ODR violation. According to the defect report 链接,"current implementations appear to give internal linkage to specializations of const-qualified variable templates" 被标准委员会认为不是他们想要的行为。

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

好像没有。