5

Similar to this question about explicit specialisation of static const class members of a template class, and this question about explicit specialisation of a template class, but my issue is with explicit specialisation of a variable template.

My 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() {}

Compile command: $CXX -std=c++14 my_specialised_literal.cc main.cc This compiles and seems to work as expected on just about every compiler version I've tried, but gives linker errors with clang-9:

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

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

Is this an ODR violation silently accepted by most compiler versions, or is clang-9 wrong in some way? If the former, I know that if I could use C++17 I could fix it by making the specialisation inline, but what is a C++14 fix for the problem?

4

1 回答 1

1

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

这是大多数编译器版本默默接受的 ODR 违规吗?

据我了解,是的。根据存储类说明符cppreference 页面,模板变量应该具有外部链接,即使它是constexpr,这意味着在翻译单元中有多个定义是违反 ODR 的。根据该页面底部链接的缺陷报告,“当前的实现似乎提供了与 const 限定变量模板的专业化的内部链接”,标准委员会认为这不是他们想要的行为。

什么是针对该问题的 C++14 修复程序?

好像一个都没有

于 2019-11-08T01:31:38.533 回答