Явная специализация внутренней структуры в области, не связанной с пространством имен

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

Эта проблема

Пожалуйста, потерпите меня, это трудно выразить словами. У меня есть шаблон класса 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 или иным образом.

Что сработало

  1. Положить неспециализированное определение is_a<U> до объявления A, И затем поместите специализированную версию с 2 аргументами шаблона вместо 1; т.е. template <> template <typename T, unsigned n> struct is_A< A<T,n> > : std::true_type {};, Почему бы и нет, но мне не очень нравится добавлять шаблонный аргумент и взорвать определение is_A тоже не так красиво...
  2. Удаление 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

1 ответ

Решение

Кажется, это работает для меня, если вы делаете, как советует компилятор: Оставьте template<>:

template <typename U>
struct is_A< A<U,n> > : public std::true_type {};
Другие вопросы по тегам