哪些成员函数可以在C++中模板化?

t3irkdon  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(92)

bounty将在2天后过期。回答此问题可获得+50的声望奖励。mascai正在寻找可靠来源的答案

有人问我一个问题
C++中哪些类函数可以模板化?(构造函数,析构函数,常量,静态)
我是否正确地理解了所有成员函数(析构函数除外)都可以模板化?

构造函数/析构函数

class A {
public:
    template<class T>
    A(T t) {
        cout << t << endl; 
    }

    /*
    template<class U>
    ~A() {  // error: destructor cannot be declared as a template
        cout << "Destructor\n";
    }*/

};

int main() {
    A a(5);
}

字符串

静态函数

是的,它可以是模板。

class A {
public:
    template< typename T>
    static double foo( vector<T> arr );

};

template< typename T>
double A::foo( vector<T> arr ){ cout << arr[0] << endl; }

int main() {
    A a;
    A::foo<int>({1, 2, 3});
}

非常量/常量成员函数

是的

class A {
public:
    template< typename T>
    double foo( vector<T> arr ) const {
        cout << arr[0] << endl;
    }
};

int main() {
    A a;
    a.foo<int>({1, 2, 3});
}

eit6fx6z

eit6fx6z1#

从技术上讲,任何成员函数都可以被“模板化”,因为这个术语包括类模板的成员函数(或者类模板的成员类,或者函数模板中的局部类,等等),它们当然可以使用模板参数来封装任何模板。真实的问题是哪些成员可以是函数模板(因此根本不是函数)。
答案很简单:任何不是(预期的)析构函数且不是**virtual的成员函数都可以是函数模板。(构造函数模板和转换函数模板不能用显式**模板参数调用,因此必须推导这些参数。)
但是请注意,无论是函数模板还是函数的特殊化都不能算作某些特殊的成员函数,即使它可以代替它们使用(由于抑制了隐式声明或更好的匹配):

struct A {
  template<class=int>
  A(int=0);          // #1, not a default constructor
  template<class T>
  A(T&);             // #2, not a copy constructor
  template<class T>
  A& operator=(T&);  // #3, not a copy-assignment operator
} a,         // calls #1
  b(a),      // calls #2
  &r=(a=b);  // calls #3

字符串
A在这里仍然有默认的复制/移动操作,因为这些操作都不会相互干扰。

gupuwyp2

gupuwyp22#

所有类方法 * 除了析构函数和复制构造函数 *(和移动构造函数?)都可以定义为类成员模板。

  • 自定义构造函数
  • 示例方法
  • 静态方法
  • 运算符(包括赋值和转换)

其他注意事项:

  • 对于可以拥有成员模板的 classes 的类型有一些限制(本地定义的类不能)。
  • 类成员模板不能是虚的,也不能重写基类中的虚函数。
  • 还有一些关于类成员模板查找的棘手细节需要考虑。
  • 从技术上讲,你可以(也许?)将默认构造函数声明为成员模板,但这样做没有意义。

参见:https://en.cppreference.com/w/cpp/language/member_template

相关问题