Явная специализация переменной шаблона - PullRequest
3 голосов
/ 22 октября 2019

Аналогично этот вопрос о явной специализации членов статического класса const класса шаблона, и этот вопрос об явной специализации класса шаблона, но моя проблема связана с явной специализациейшаблона переменной.

Мой 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 для решения проблемы?

1 Ответ

0 голосов
/ 08 ноября 2019

Мне кажется, я решил это:

Является ли это нарушением ODR, которое молча принимается большинством версий компилятора?

Насколько я понимаю, да. Согласно странице спецификаций класса хранения cppreference, переменная шаблона должна иметь внешнюю связь, даже если она constexpr, что означает, что наличие нескольких определений в единице перевода является нарушением ODR. Согласно сообщению о дефекте 1011 *, связанному внизу этой страницы, «текущие реализации, по-видимому, дают внутреннюю связь со специализациями шаблонов переменных с константной квалификацией», которое комитет по стандартам посчитал не таким поведениемнамерение.

Что такое исправление в C ++ 14 для этой проблемы?

Похоже, его нет.

...