这个问题在这里已经有了答案:C++ syntax for explicit specialization of a template function in a template class? (9 个回答) 7 年前关闭。
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,如果不明确专门化包含类,您就无法专门化成员函数,因此一种解决方案是让 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>)
{
}
};
只需将模板特化放在类声明之外。 gcc 不允许内联模板特化。
作为另一种选择,仅删除行模板<> 似乎对我有用。
template<>
也对我有用。
更好的是:您可以将部分专业化与默认模板参数结合起来。这种方式对 VC++ 代码的修改很小,因为不需要修改对专用函数的调用。
template <typename TL, class Dummy=int>
void Verify(int position, int constraints[])
{
}
template <class Dummy=int>
void Verify<int, Dummy>(int, int[])
{
}
=
之后指定的模板参数 (14.3)。可以为任何类型的模板参数(类型、非类型、模板)指定默认模板参数。可以在类模板声明或类模板定义中指定默认模板参数。不应在函数模板声明或函数模板定义中指定默认模板参数,也不应在模板参数列表中指定类模板成员的定义。"
您可能无法明确专门化成员模板,但可以部分专门化它。如果您添加第二个参数“int dummyParam”并将其添加到专业化中,它应该适用于两个编译器。
并不是说我在 10 多秒前就知道这一点,而是在谷歌上搜索同样的错误,我遇到了 this link,它适用于我的成员模板专业化。
不定期副业成功案例分享
How can we make this language any more difficult to read and write?