模板变量的显式特化
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?
好像没有。
类似于
我的 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?
好像没有。