Как явно специализировать шаблон функции из другого пространства имен?

Для удобства чтения я хотел бы специализировать шаблон функции, близкий к определению класса, который объявлен внутри пространства имен:

#include <iostream>

template<typename T> void my_function() {
    std::cout << "my_function default" << std::endl;
}

namespace Nested {
    class A {};
    template<> void my_function<A>() {
        std::cout << "my_function specialization for A" << std::endl;
    }
}

Однако с помощью приведенного выше кода я получаю следующую ошибку от clang++ 4.0:

 error: no function template matches function template specialization 'my_function'

Это кажется проблемой с пространством имен. Как я могу заставить работать вышеперечисленное (без перемещения специализации функции шаблона из Nested Пространство имен)?

Изменить: я также попытался добавить ::my_function по специальности:

test.cpp: error: definition or redeclaration of 'my_function' cannot name the global scope
        template<> void ::my_function<A>() {
                        ~~^

1 ответ

Решение

Это невозможно, специализация должна находиться в том же пространстве имен, что и сам шаблон:

14.7.3 Явная специализация [temp.expl.spec]

2 Явная специализация должна быть объявлена ​​в пространстве имен, включающем специализированный шаблон. Явная специализация, для которой идентификатор объявления или class-head-name не определен, должна быть объявлена ​​в ближайшем включающем пространстве имен шаблона, или, если пространство имен является встроенным (7.3.1), в любом пространстве имен из его входящего набора пространств имен. Такое заявление также может быть определением. Если декларация не является определением, специализация может быть определена позже (7.3.1.2).

поэтому вы должны переписать свой код следующим образом:

namespace Nested {
class A {};
} // namespace Nested

template<> void my_function<Nested::A>() {
    std::cout << "my_function specialization for A" << std::endl;
}
Другие вопросы по тегам