8

Given the following code, does Foo have copy constructor? Is it safe to use Foo with STL containers?

class Foo
{
public:
   Foo() {}

   template <typename T>
   Foo(const T&) {}   
};
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242

3 Answers3

10

The standard explicitly says that a copy constructor is a non-templated constructor that takes a reference to a possibly const-volatile object of the same type. In the code above you have a conversion but not copy constructor (i.e. it will be used for everything but copies, where the implicitly declared constructor will be used).

Does Foo have a copy constructor?

Yes, the implicitly declared/defined copy constructor.

Is it safe to use Foo with standard library containers?

With the current definition of Foo it is, but in the general case, it depends on what members Foo has and whether the implicitly defined copy constructor manages those correctly.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • What happens if this is declared before the template `Foo(const Foo&) = delete;`? Does the class now have no copy constructor or does the template get called instead? – orlp Sep 11 '12 at 16:52
  • 1
    If the copy constructor is deleted, then the class doesn't have one. ;-) – Bo Persson Sep 11 '12 at 16:54
  • @nightcracker then there is no copy constructor and the compiler gives an error (unless you have an expression where e.g. the move copy constructor could have been used). The key is that the copy constructor is *non-templated*. – juanchopanza Sep 11 '12 at 16:55
  • Where *does* the implicit copy constructor get used? It seems like only for when this type is used as a subobject of a larger type that has a defaulted copy constructor. – Ben Voigt May 04 '14 at 18:54
  • @BenVoigt: I am not sure I understand the comment. In the code it is not used, but the question talks about being able to use this type in a container (with the concern placed on the copy-constructor). Maybe I should make it clearer that the implicitly-declared copy constructor is only defined if *used*? Is that your concern? The copy constructor will be defined whenever an object of this type is copied, it need not be a part of a larger object (say: `Foo f, g(f);` – David Rodríguez - dribeas May 05 '14 at 13:42
4

According to the Standard, a copy-constructor must be one of the following signature:

Foo(Foo &);
Foo(Foo const &);
Foo(Foo volatile &);
Foo(Foo const volatile &);

Foo(Foo&, int = 0, );
Foo(Foo&, int = 0, float = 1.0); //i.e the rest (after first) of the 
                                 //parameter(s) must have default values!

Since the template constructor in your code doesn't match with the form of any of the above, that is not copy-constructor.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Foo has a compiler generated copy constructor, which cannot be replaced by the template conversion constructor you have provided.

Foo f0;
Foo f1(f0); // calls compiler-synthesized copy constructor
Foo f2(42); // calls template conversion constructor with T=int
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • This seems NOT to actually call the copy constructor. http://stackoverflow.com/questions/11037644/how-do-i-get-the-copy-constructor-called-over-a-variadic-constructor – Ben Voigt May 04 '14 at 18:51