【发布时间】:2019-10-21 23:19:39
【问题描述】:
类似于 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_specialised_literal.cc main.cc
这编译并且似乎在我尝试过的几乎每个编译器版本上都按预期工作,但是使用 clang-9 给出链接器错误:
/tmp/main-ec49c7.o:(.rodata+0x0): `val'的多重定义
/tmp/my_specialised_literal-521691.o:(.rodata+0x0): 首先在这里定义
这是大多数编译器版本默默接受的 ODR 违规,还是 clang-9 在某些方面是错误的?如果是前者,我知道如果我可以使用 C++17,我可以通过专门化 inline 来修复它,但是 C++14 修复该问题的方法是什么?
【问题讨论】:
-
我认为你的
constexpr变量应该是static。其他可能的替代方案:(1) 函数,(2) 静态常量或 (3)enum值。 -
@Phil1970
static是我尝试的第一件事,它适用于 clang,但 gcc 给出编译错误:explicit template specialization cannot have a storage class。
标签: c++ templates c++14 linker-errors explicit-specialization