在非名称空间作用域中的显式特化
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中,它编译好。 任何人都可以请让我知道解决方法?
VC ++在这种情况下是不兼容的 – 显式的特化必须在名称空间范围内。 C ++ 03, §14.7.3/ 2 :
明确的特殊化应在模板所属的名称空间中声明,或者对于成员模板,在封闭类或封闭类模板所属的名称空间中声明。
类模板的成员函数,成员类或静态数据成员的显式特化应在类模板所属的名称空间中声明。
另外你还有一个问题,就是因为C ++ 03, §14.7.3/ 3 ,你不能明确地专门化包含类,所以你不能专门化成员函数,所以一个解决scheme就是让Verify()
转发到一个可能专用的,免费function:
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); } };
解决这个问题的另一种方法是委托给一个私有函数并重载该函数。 这样您仍然可以访问*this
成员数据和外部模板参数types。
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>) { } };
只需在类声明之外使用模板专门化。 gcc不允许内联模板专门化。
作为另一种select,只是删除行模板<>似乎为我工作。
更好的是:你可以将部分专业化与默认的模板参数结合起来。 这样对VC ++代码的修改是很小的,因为对专用函数的调用不需要修改。
template <typename TL, class Dummy=int> void Verify(int position, int constraints[]) { } template <class Dummy=int> void Verify<int, Dummy>(int, int[]) { }
您可能无法明确地专门化成员模板,但您可以部分专门化它。 如果添加第二个参数“int dummyParam”,并将其添加到专门化,它应该与两个编译器一起工作。
不是我十多秒前就知道这一点,而是用同样的错误search,我跑到这个链接 ,它为我的成员模板专业化工作。