为什么不允许在类中专用化成员函数模板
Why is it not allowed to specialize a member function template within a class?
当我尝试在类定义/声明中专门化公共成员函数模板时:
#include <iostream>
class surfaceMesh
{
public:
// Uncomment for Version 0 and 1
class AREA_AVERAGE {};
class ANGLE_AVERAGE {};
template<class Average>
void vertexNormals() {}
// Uncomment: Version 0
//template<>
//void vertexNormals<AREA_AVERAGE> ()
//{
//std::cout << "AREA_AVERAGE" << std::endl;
//}
//template<>
//void vertexNormals<ANGLE_AVERAGE> ()
//{
//std::cout << "ANGLE_AVERAGE" << std::endl;
//}
};
// Uncommend for version 1
template<>
void surfaceMesh::vertexNormals<surfaceMesh::AREA_AVERAGE> ()
{
std::cout << "AREA_AVERAGE" << std::endl;
};
template<>
void surfaceMesh::vertexNormals<surfaceMesh::ANGLE_AVERAGE> ()
{
std::cout << "ANGLE_AVERAGE" << std::endl;
};
int main()
{
surfaceMesh m;
m.vertexNormals<surfaceMesh::AREA_AVERAGE>();
m.vertexNormals<surfaceMesh::ANGLE_AVERAGE>();
return 0;
}
对于版本 0,错误为:
main.cpp:19: error: template-id ‘vertexNormals<mesh::AREA_AVERAGE>’ in declaration of primary template
main.cpp:24: error: explicit specialization in non-namespace scope ‘class mesh’
main.cpp:25: error: template-id ‘vertexNormals<mesh::ANGLE_AVERAGE>’ in declaration of primary template
main.cpp:25: error: ‘void mesh::vertexNormals()’ cannot be overloaded
main.cpp:19: error: with ‘void mesh::vertexNormals()’
版本 1 编译并运行。当然,通常我会将类声明和定义分开,但我真的很想知道为什么会发生这种情况。
另外,这是专门化界面的好方法吗?另一种选择是重载函数 vertexNormals 以获取 AREA_AVERAGE 或 ANGLE_AVERAGE 的对象,但这只是一个类型告诉我我将使用哪种函数,它不应该被实例化,所以使用模板"感觉"像一个正确的选择。
为什么不允许在类中专用化成员函数模板?
因为这是C++标准规定的规则。
至于你想要什么,更好的方法是使用函数重载而不是函数专用化,因为:
class surfaceMesh
{
public:
// Uncomment for Version 0 and 1
class AREA_AVERAGE {};
class ANGLE_AVERAGE {};
template<class Average>
void vertexNormals()
{
//invoke the function overload
vertexNormals(static_cast<Average*>(0));
}
private:
//make the overloads private, so client will not call them!
void vertexNormals(AREA_AVERAGE *)
{
std::cout << "AREA_AVERAGE" << std::endl;
}
void vertexNormals(ANGLE_AVERAGE*)
{
std::cout << "ANGLE_AVERAGE " << std::endl;
}
};
表达式的类型static_cast<Average*>(0)
可帮助编译器选择正确的重载。
相关文章:
- 是否可以获取成员函数模板参数的拥有对象?
- 实例化多种类型的成员函数模板
- C++:递归成员函数模板
- C++成员函数模板将成员函数指针作为模板参数
- 类和成员函数模板专用化出错
- 调用类模板的成员函数模板
- 课堂中成员函数模板的明确实例
- 专用和/或重载具有可变参数的成员函数模板
- 具有可变参数的类成员函数模板部分专用化
- 将 PIMPL 习惯用法与成员函数模板一起使用(无需预先了解所有可能的数据类型)
- 澄清了使用 enable_if 的成员函数模板专用化
- 是否可以从指向成员函数模板参数的指针推断类类型
- 成员函数模板推演指南或其他方法让编译器知道如何调用函数
- 成员函数模板不会在 clang 上编译,但在 GCC 上编译
- 类模板的成员函数模板找不到定义,尽管存在显式实例化。不链接
- 成员函数模板参数的部分专业化
- 在C++中创建成员函数模板专用化
- 要求派生类提供成员函数模板
- 实例化错误后成员函数模板的专业化,以及成员函数的顺序
- 使用提升::函数的成员函数模板