mascai
mascai

Reputation: 1870

Which member functions can be templated in C++?

I was asked a question

Which class functions can be templated in C++? (constructor, destructor, const, static)

Did I understand correctly that all member functions (except destructor) can be templated?

Constructor / destructor

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);
}

Static function

Yes, it can be template.

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});
}

Non-constant / constant member function

Yes.

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});
}

Upvotes: 4

Views: 281

Answers (2)

Davis Herring
Davis Herring

Reputation: 40013

Technically, any member function can be templated, since that term includes member functions of class templates (or of member classes of class templates, or local classes in function templates, etc.) that can of course use the template parameters for whatever enclosing template. The real question is which members can be function templates (and thus not functions at all).

The answer is simple: any member function that is not a (prospective) destructor and not virtual can instead be a function template. (Constructor templates and conversion function templates can’t be invoked with explicit template arguments, so those have to be deduced.)

Note, though, that neither a function template nor a specialization of one can count as certain special member functions, even if it can be used in their stead (thanks to suppressing the implicit declaration or being a better match):

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 still has defaulted copy/move operations here because none of these interfere.

Upvotes: 4

Ryan F
Ryan F

Reputation: 11

All class methods except the destructor and copy constructors (and move constructors?) can be defined as class member templates.

  • Custom constructors
  • Instance methods
  • Static methods
  • Operators (including assignment and conversion)

Other considerations:

  • There are some restrictions on the types of classes which can have member templates (locally defined classes cannot).
  • Class member templates cannot be virtual nor can they override virtual functions in a base class.
  • There are also some tricky details of class member template lookup to consider.
  • Technically you could (probably?) declare the default constructor to be a member template, but it would not make sense to do so.

See: https://en.cppreference.com/w/cpp/language/member_template

Upvotes: 0

Related Questions