为什么不允许在类中专用化成员函数模板

Why is it not allowed to specialize a member function template within a class?

本文关键字:成员 函数模板 专用 不允许 为什么      更新时间:2023-10-16

当我尝试在类定义/声明中专门化公共成员函数模板时:

#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)可帮助编译器选择正确的重载。