我的代码适用于VC9(Microsoft Visual C ++ 2008 SP1)但不适用于GCC 4.2(在Mac上):
struct tag {};
template< typename T >
struct C
{
template< typename Tag >
void f( T ); // declaration only
template<>
inline void f< tag >( T ) {} // ERROR: explicit specialization in
}; // non-namespace scope 'structC<T>'
我理解GCC希望我在课外移动我的显式专业,但我无法弄清楚语法。有什么想法吗?
// the following is not correct syntax, what is?
template< typename T >
template<>
inline void C< T >::f< tag >( T ) {}
答案 0 :(得分:32)
如果没有明确地专门化包含类,则无法专门化成员函数 但是你可以做的是向部分专用类型的成员函数的前向调用:
template<class T, class Tag>
struct helper {
static void f(T);
};
template<class T>
struct helper<T, tag1> {
static void f(T) {}
};
template<class T>
struct C {
// ...
template<class Tag>
void foo(T t) {
helper<T, Tag>::f(t);
}
};
答案 1 :(得分:8)
14.7.3.2:
2.应在名称空间中声明显式专门化 哪个模板是成员,或者,对于成员模板,在 封闭类或封闭类模板所在的命名空间 成员。成员函数的明确特化,成员 类模板的类或静态数据成员应声明 类模板所属的命名空间。
此外,您无法部分专门化功能。 (虽然我对你案件中的细节不确定,但那将是最后一击。)
你可以这样做:
#include <iostream>
struct true_type {};
struct false_type {};
template <typename T, typename U>
struct is_same : false_type
{
static const bool value = false;
};
template <typename T>
struct is_same<T, T> : true_type
{
static const bool value = true;
};
struct tag1 {};
struct tag2 {};
template< typename T >
struct C
{
typedef T t_type;
template< typename Tag >
void foo( t_type pX)
{
foo_detail( pX, is_same<Tag, tag1>() );
}
private:
void foo_detail( t_type, const true_type& )
{
std::cout << "In tag1 version." << std::endl;
}
void foo_detail( t_type, const false_type& )
{
std::cout << "In not tag1 version." << std::endl;
}
};
int main(void)
{
C<int> c;
c.foo<tag1>(int());
c.foo<tag2>(int());
c.foo<double>(int());
}
虽然这有点难看。
答案 2 :(得分:1)
试试这个:
template <> template<typename T> inline void C<T> :: foo<tag2>(T) {}
答案 3 :(得分:1)
问这个问题。这应该起作用:
struct tag {};
template< typename T >
struct C {
template< typename Tag, typename std::enable_if<std::is_same<Tag, tag>::value, int>::type = 0>
void f( T ){
std::cout<<"tag type" <<std::endl;
}
template< typename Tag, typename std::enable_if<!std::is_same<Tag, tag>::value, int>::type = 0>
void f( T ){
std::cout<<"non tag type" <<std::endl;
}
};
答案 4 :(得分:0)
我知道这可能不会让您满意,但我不相信您可能没有专门化的非专业化结构。
template<>
template<>
inline void C< tag1 >::foo< tag2 >( t_type ) {}
答案 5 :(得分:0)
虽然代码可能不合规,但一种实用的解决方案是切换到 clang,它可以正常工作。