Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit specialization of template variable

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?

like image 786
John Ilacqua Avatar asked Nov 06 '22 12:11

John Ilacqua


1 Answers

I think I've worked this out:

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

From my understanding, yes. According to the 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 linked at the bottom of that page, "current implementations appear to give internal linkage to specializations of const-qualified variable templates", which was deemed by the standards committee to not be the behaviour they intend.

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

It seems there isn't one.

like image 189
John Ilacqua Avatar answered Nov 15 '22 06:11

John Ilacqua