Специализация члена шаблона класса

Я специализирую функции-члены класса шаблона в заголовочном файле следующим образом:

#pragma once

#include <iostream>

template<class T>
struct Test
{
void Print() { }
};

template<>
void Test<int>::Print()
{
std::cout << "int" << std::endl;
}

Правильно ли помещать специализацию в заголовочный файл (не будучи встроенным), или он должен быть в файле cpp? Он прекрасно компилируется, как показано выше (с использованием VS2012), но я довольно удивлен, что не получаю несколько ошибок компоновщика определений.

2

Решение

ODR требует ровно одного определения для не встроенных функций, которые ODR используемый (это означает, что для функций он может быть вызван).

Цитирую n3485, [basic.def.odr]

4 Каждая программа должна содержать ровно одно определение
каждая не встроенная функция или переменная, которая используется в этом
программа; Диагностика не требуется.

Тогда есть исключение для шаблоны (т.е. не для функций):

6 Может быть несколько определений типа класса […], шаблона класса, нестатического шаблона функции, статического члена данных
шаблона класса, функция-член шаблона класса или шаблонная специализация для
какие параметры шаблона не указаны
в программе при условии, что […]

[акцент мой]

Явная специализация шаблона не является шаблоном. Например, явно специализированный шаблон класса — это класс (со странным именем). Следовательно, ваше предположение верно, и множественные определения для явно специализированных членов шаблонов классов нарушают ODR.

С g ++ 4.8.1 я даже получаю ошибку компоновщика в такой программе; Обратите внимание, что я использовал функцию ODR. Диагностика нарушения ODR не требуется.

2

Другие решения

Размещение специализации в заголовочном файле является канонической формой (как boost делает), это не нарушает ODR.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector