Explicit specialization in non-namespace scope

template<typename T>
class CConstraint
{
public:
CConstraint()
{
}


virtual ~CConstraint()
{
}
    

template <typename TL>
void Verify(int position, int constraints[])
{
}


template <>
void Verify<int>(int, int[])
{
}
};

Compiling this under g++ gives the following error:

Explicit specialization in non-namespace scope 'class CConstraint'

In VC, it compiles fine. Can anyone please let me know the workaround?

108607 次浏览

VC + + 在这种情况下是不兼容的——显式的专门化必须在名称空间范围内:

应该在模板为成员的命名空间中声明显式专门化,或者对于成员模板,在包含类或包含类模板为成员的命名空间中声明显式专门化。
类模板的成员函数、成员类或静态数据成员的显式专门化应在类模板为成员的命名空间中声明。

此外,由于 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);
}
};

另一种解决方法是委托一个私有函数并重载该函数。这样,您仍然可以访问 *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>)
{


}
};

您可能不能 显式地专门化的成员模板,但您可以 只是一部分专门化它。如果添加第二个参数“ intDummyParam”并将其添加到专门化中,那么它应该可以同时使用这两个编译器。

我并不是在10秒钟之前就知道这一点,但是在谷歌上搜索同样的错误时,我遇到了 这个链接,它对我的成员模板专门化起了作用。

甚至更好: 您可以将部分专门化与默认模板参数结合起来。通过这种方式,对 VC + + 代码的修改很小,因为不需要修改对专门函数的调用。

template <typename TL, class Dummy=int>
void Verify(int position, int constraints[])
{
}


template <class Dummy=int>
void Verify<int, Dummy>(int, int[])
{
}

只需将模板专门化置于类声明之外。 Gcc 不允许内联模板专门化。

作为另一种选择,只需删除行 范本 < > 似乎对我有用。