1

У меня есть класс шаблона и функция-член шаблона:Статическая функция-член шаблона для шаблонного класса

template<class T1> 
struct A{ 
    template<class T2> 
    static int f(){return 0;} 
}; 

Я хочу специализироваться для случая, когда T1 и T2 таких же,

Например, определите случай A<T>::f<T> для любых T.

, но я не могу найти комбинацию ключевых слов для достижения этой цели.

Как я могу частично (?) Специализировать комбинацию класса шаблона и статической функции шаблона?


Это мои неудачные попытки, и сообщения об ошибках:

1) Специализируется внутри класса: fatal error: cannot specialize a function 'f' within class scope)

template<class T1> 
struct A{ 
    template<class T2> 
    static int f(){return 0;} 

    template<> 
    static int f<T1>(){return 1;} 

}; 

2) Специализируются вне класса "одновременно" : fatal error: cannot specialize a member of an unspecialized template

template<class T> 
void A<T>::f<T>(){return 1;} 

3) Специализируются использованием template<>: fatal error: too few template parameters in template redeclaration

template<> template<class T> 
void A<T>::f<T>(){return 1;} 

4) Инверсия порядка: fatal error: cannot specialize (with 'template<>') a member of an unspecialized template

template<class T> template<> 
void A<T>::f<T>(){return 1;} 

5) специализироваться весь класс (на основе ошибки попытки 3): fatal error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list

template<class T> 
struct A<T>{ 
    template<> 
    static int f<T>(){return 1;} 
}; 

6) Специализируйте класс, но не функцию (?): fatal error: too few template parameters in template redeclaration template<> template<class T1>

template<> template<class T> 
int A<T>::f(){return 0;} 

Я использовал clang 3.5 C++14 для генерации сообщений об ошибках.

ответ

2

Вы не можете частично специализировать функцию.

Вы можете направить работу другого типа:

template<class T1> 
struct A; 

template<class T1, class T2> 
struct A_helper { 
    static int f() { 
    return A<T1>::f_simple<T2>(); 
    } 
}; 
template<class T> 
struct A_helper<T,T> { 
    static int f() { 
    return A<T>::f_special(); 
    } 
}; 

template<class T1> 
struct A{ 
    template<class T2> 
    static int f(){return A_helper<T1,T2>::f()} 
    template<class T2> 
    static int f_simple(){return 0;} 
    static int f_special(){return -1;} 
}; 

или, более просто, без каких-либо A_helper:

template<class T1> 
struct A{ 
    template<class T2> 
    static int f(){return f2<T2>(std::is_same<T1,T2>{});} 
    template<class T2> 
    static int f2(std::true_type){ 
    static_assert(std::is_same<T1,T2>{}, "bob!"); 
    return -1; 
    } 
    tempalte<class T2> 
    static int f2(std::false_type){return -1;} 
}; 

вы можете использовать тег диспетчеризацию.

Другой подход:

template<class T>struct tag{}; 

template<class T1> 
struct A{ 
    template<class T2> 
    static int f(){return f2(tag<T2>{});} 
    template<class T2> 
    static int f2(tag<T2>) {return 0;} 
    static int f2(tag<T1>) {return -1;} 
}; 

где мы непосредственно направить на тип T2.

Смежные вопросы