template<typename T>
class CConstraint
{
public:
CConstraint()
{
}
virtual ~CConstraint()
{
}
template <typename TL>
void Verify(int position, int constraints[])
{
}
template <>
void Verify<int>(int, int[])
{
}
};
在g ++下编译它会产生以下错误:
非命名空间范围'class CConstraint'
中的显式特化在VC中,它编译得很好。任何人都可以让我知道解决方法吗?
答案 0 :(得分:92)
在这种情况下,VC ++是不兼容的 - 显式特化必须在命名空间范围内。 C ++ 03,§14.7.3/ 2 :
显式特化应在模板所属的命名空间中声明,或者对于成员模板,在封闭类或封闭类模板所属的命名空间中声明。
应该在类模板所属的名称空间中声明类模板的成员函数,成员类或静态数据成员的显式特化。
此外,您还有一个问题,即由于C ++ 03,§14.7.3/ 3 而没有明确地专门化包含类,因此无法专门化成员函数,因此一个解决方案就是让Verify()
转发一个可能是专门的免费功能:
namespace detail {
template <typename TL> void Verify (int, int[]) {}
template <> void Verify<int>(int, int[]) {}
}
template<typename T> class CConstraint {
// ...
template <typename TL> void Verify(int position, int constraints[]) {
detail::Verify<TL>(position, constraints);
}
};
答案 1 :(得分:84)
另一种解决方法是委托私有函数并重载该函数。这样,您仍然可以访问*this
的成员数据和外部模板参数类型。
template<typename T>
struct identity { typedef T type; };
template<typename T>
class CConstraint
{
public:
template <typename TL>
void Verify(int position, int constraints[])
{
Verify(position, constraints, identity<TL>());
}
private:
template<typename TL>
void Verify(int, int[], identity<TL>)
{
}
void Verify(int, int[], identity<int>)
{
}
};
答案 2 :(得分:11)
只需在类声明之外进行模板特化。 gcc不允许内联模板专业化。
作为另一种选择,只需删除行 模板&LT;&GT; 似乎对我有用。
答案 3 :(得分:4)
更好:您可以将部分特化与默认模板参数结合使用。这种方式对VC ++代码的修改很小,因为不需要修改对专用函数的调用。
template <typename TL, class Dummy=int>
void Verify(int position, int constraints[])
{
}
template <class Dummy=int>
void Verify<int, Dummy>(int, int[])
{
}
答案 4 :(得分:1)
您可能无法明确专门化成员模板,但您可以部分对其进行专门化。如果你添加第二个参数“int dummyParam”并将其添加到专门化,它应该适用于两个编译器。
不是我在10多秒前知道这一点,而是在Google上搜索同样的错误,我遇到this link并且它适用于我的会员模板专业化。