2
votes

This page shows that std::shared_ptr has a templated and a non-templated version of copy/move constructors ((9) and (10) on the page). Similarly, it also has two versions of copy/move assignment operator (see here).

Why do we need the non-templated version? Wouldn't the templated version alone suffice?

1
A template is never(!) a copy/move constructor - user2249683
@DieterLücking If we delete the (non-templated) copy/move constructors, what kind of code will break? - Zizheng Tai
... without the non template constructors default constructors might get generated (if possible). - user2249683
@DieterLücking however, it can "hide" the copy/move constructor (e.g. when copy from a non-const lvalue). - sehe

1 Answers

3
votes

The templated version is not a copy constructor. According to the standard §12.8[class.copy]/2 we have that:

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).

And similarly, the templated version is also not a copy assignment operator, according to §12.8[class.copy]/17:

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.

The same holds true for move constructors (at §12.8[class.copy]/3):

A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const X&&, volatile X&&, or const volatile X&&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).

and move assignment operators, at §12.8[class.copy]/19:

A user-declared move assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.