Я знаю, что есть много постов оЯвная специализация в области без пространства имен«; Я уже прочитал большинство из них, но (если я не очень хорошо понял ответы), они не отвечают на этот конкретный вопрос. На самом деле, я нашел обходной путь в своей программе, но мне интересно знать, «реальное решение» этой проблемы, если оно есть.
Пожалуйста, потерпите меня, это трудно выразить словами. У меня есть шаблон класса A<typename T, unsigned n>
, Я хочу определить проверку типов как внутреннюю структуру шаблона is_A<typename U>
который проверяет, если U
это какой-то A
, Эта структура наследуется от std::false_type
как есть, и я специализируюсь на этом, чтобы извлечь из std::true_type
для типов шаблонов A<U,n>
,
Почему я хочу это сделать? Потому что я хочу определить метод шаблона A::method<U>
который ведет себя по-другому, когда U
это какой-то A
или иным образом.
is_a<U>
до объявления A
, И затем поместите специализированную версию с 2 аргументами шаблона вместо 1; т.е. template <> template <typename T, unsigned n> struct is_A< A<T,n> > : std::true_type {};
, Почему бы и нет, но мне не очень нравится добавлять аргумент шаблона и взорвать определение is_A
тоже не так красиво …is_A
и использовать другую проверку типов для method
который характеризует именно тот тип, который я ожидаю (т.е., белый список вместо черного списка).Есть ли другой способ, кроме этих обходных путей, который позволяет написать что-то похожее на следующий заголовок?
Вот самый маленький заголовок, который я мог написать, чтобы воспроизвести ошибку:
#ifndef __EXAMPLE__
#define __EXAMPLE__
#include <type_traits>
namespace name
{template <typename T, unsigned n>
class A
{
public:
/**
* Type checkers
*/
template <typename U>
struct is_A : public std::false_type {};
template <> template <typename U>
struct is_A< A<U,n> > : public std::true_type {};
/**
* Specialized method
*/
// Version taking input of type A<U,n>
template <typename U>
void method( const A<U,n>& other ) {}
// Version taking inputs of other types
template <typename U,
typename = typename std::enable_if< !is_A<U>::value >::type >
void method( const U& x ) {}
};}
#endif
Вот ошибка, которую я получаю при компиляции файла cpp, включающего этот заголовок:
.h:21:12: error: explicit specialization in non-namespace scope 'class name::A<T, n>'
.h:30:7: error: too many template-parameter-lists
.h:35:7: error: too many template-parameter-lists
Кажется, это работает для меня, если вы делаете, как советует компилятор: Оставьте template<>
:
template <typename U>
struct is_A< A<U,n> > : public std::true_type {};
Других решений пока нет …