4

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});
}
7
  • 1
    You can only have a template constructor when implicit argument deduction can be used, not in all cases: stackoverflow.com/questions/3960849/c-template-constructor
    – VLL
    Commented Mar 29, 2023 at 10:16
  • 3
    A class can only have one destructor, and a template is the means of automatically generating a family of functions. So having a templated destructor is not allowed (essentially because it would be pointless and potentially misleading to have one). A class can have as many (static or non-static) other member functions as judged appropriate to its design - so they can (if appropriate) be templated.
    – Peter
    Commented Mar 29, 2023 at 10:22
  • 1
    I also tried to define a template cast operator. It works. But it seems you can not define a template cast to another type (like this: template<typename T> operator double() const { return (double)T(); })
    – Caduchon
    Commented Mar 29, 2023 at 14:01
  • 1
    @Caduchon Curiously, you can in fact define a templated conversion operator like this - but there doesn't appear to be any syntax to actually call it. So it's mostly of academic interest. Commented Apr 1, 2023 at 15:06
  • 1
    @Peter a class template can certainly have multiple destructor definitions with different requires clauses. Commented Jan 4 at 13:33

2 Answers 2

4
+50

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.

0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.