22

I read that template copy-con is never default copy onstructor, and template assignment-op is never a copy assignment operator.

I couldn't understand why this restriction is needed and straight away went online to ideone and return a test program but here copy constructor never gets called on further googling I came across templatized constructor and tried that but still it never calls copy constructor.

#include <iostream>
using namespace std;

template <typename T> class tt
{
    public :
    tt()
    {
        std::cout << std::endl << "   CONSTRUCTOR" << std::endl;
    }
    template <typename U> const tt<T>& operator=(const tt<U>& that){std::cout << std::endl << "   OPERATOR" << std::endl;}
    template <typename U> tt(const tt<U>& that)
    {
        std::cout << std::endl << "    COPY CONSTRUCTOR" << std::endl;
    }
};


tt<int> test(void)
{
    std::cout << std::endl << "      INSIDE " << std::endl; tt<int> a; return a;
}

int main() {
    // your code goes here
    tt<int> a ; a = test();

    return 0;
}

Can someone explain me the whole reason behind putting this restriction and also how to write a copy constructor of template class.

Thanks

anonymous
  • 1,920
  • 2
  • 20
  • 30
  • 2
    [Copy-elision.](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) – David G Oct 03 '13 at 19:06
  • 1
    There is no "default copy constructor". There is only *one* copy constructor. A template is never it. – Kerrek SB Oct 03 '13 at 19:10
  • I edited code and ran it in ideone but still copy constructor do not get called. but I also not able to understand reason behind this restriction – anonymous Oct 03 '13 at 19:10

2 Answers2

32

I can't comment on why this is how it is, but here's how you write a copy constructor and assignment operator for a class template:

    template <class T>
    class A
    {
      public:
        A(const A &){}
        A & operator=(const A& a){return *this;}
    };

and that's it.
The trick here is that even though A is a template, when you refer to it inside the class as A (such as in the function signatures) it is treated as the full type A<T>.

SirGuy
  • 10,660
  • 2
  • 36
  • 66
  • 4
    @Daniel That's because `A` also refers to the full type of the class, `A` is just a shorthand you can use inside the class. – SirGuy Nov 13 '16 at 23:03
  • 1
    Which means that the constructor could also be written as `A(const A &){}`. – Moberg Oct 28 '20 at 09:58
  • 1
    Seems that A doesn't work in C++20 and plain A is required... ? –  Aug 25 '21 at 17:57
25

There are strict rules what constitutes a copy constructor (cf. C++11, 12.8):

  • It is not a template.

  • For a class T, its first argument must have type T & or T const & or T volatile & or T const volatile &.

  • If it has more than one argument, the further arguments must have default values.

If you do not declare a copy constructor, a copy constructor of the form T::T(T const &) is implicitly declared for you. (It may or may not actually be defined, and if it is defined it may be defined as deleted.)

(The usual overload resolution rules imply that you can have at most four copy constructors, one for each CV-qualification.)

There are analogous rules for move constructors, with && in place of &.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • @Nikos: How do we know that? How do you reconcile that knowledge with http://eel.is/c++draft/class.mem#class.copy.ctor-1.sentence-1? – Kerrek SB Sep 10 '19 at 22:57