我正在尝试在类型Outer<P>::Inner
上专门化P
,如下所示,它似乎可以工作(在gcc 4.5.3和Visual Studio 2008上),直到成员变量{{1} }在Inner i
中声明。是否可以在没有专门化Outer<P>
的情况下声明Inner i
?
Outer<P>
答案 0 :(得分:2)
必须在命名空间级别完成专业化。因此,最简单的方法是在命名空间级别声明Inner
:
template <typename T>
struct Outer_Inner
{
Outer_Inner()
{
std::cout << "Generic version ..." << std::endl;
}
};
template <>
struct Outer_Inner<bool>
{
Outer_Inner()
{
std::cout << "Specialization ..." << std::endl;
}
};
template<typename T>
struct Outer
{
Outer() : i()
{
}
Outer_Inner<T> i; // no error anymore
};
在C ++ 11中,有一种解决方法可以在类中定义所有内容,但我不推荐它。
template<typename T>
struct Outer
{
Outer() : i()
{
}
struct generic_inner
{
generic_inner()
{
std::cout << "Generic version ..." << std::endl;
}
};
struct special_inner
{
special_inner()
{
std::cout << "Specialization ..." << std::endl;
}
};
typename std::conditional<std::is_same<T, bool>::value,
special_inner, generic_inner>::type i;
};
答案 1 :(得分:0)
使i
a(共享)指针似乎可以正常工作
template<typename T>
struct Outer
{
Outer() : i( new Inner() )
{
}
struct Inner;
boost::shared_ptr<Inner> i;
};
这就是我的想法。原始代码Inner
在Outer
之后声明,应该如此。因此,i
的大小在声明时是未知的。在上面的代码段中,i
是一个指针,即使尚未定义Inner
,其大小也已知。
在声明Inner
之前,在Outer
内专门i
,“在Visual Studio 2008中工作”但在gcc 4.5.3中失败,因为标准禁止它。 / p>
然而,该标准允许在类范围内进行部分特化。这使得有一个非指针成员i
虽然可以在虚拟参数T2=T1
上进行模板化,如下所示,尽管我认为我将使用(智能)指针版本。
template<typename T1>
struct Outer
{
template<typename T2,bool>
struct Inner;
template<typename T2>
struct Inner<T2,true>
{
Inner()
{
std::cout << "# Specialization ..." << std::endl;
}
};
template<typename T2>
struct Inner<T2,false>
{
Inner()
{
std::cout << "# Generic version ..." << std::endl;
}
};
Outer()
{
}
Inner<T1,boost::is_same<T1, bool>::value> i;
};