Home > Back-end >  I'm reading "C Templates: The Complete Guide" and there is something that I don
I'm reading "C Templates: The Complete Guide" and there is something that I don

Time:06-26

It says:

A function generated from a function template is never equivalent to an ordinary function even though they may have the same type and the same name. This has two important consequences for class members:

  • A constructor generated from a constructor template is never a default copy constructor.

Firstly, I don't understand how that conclusion came from the first statement.

Secondly, when I try to simulate that conclusion, it gives me an error that it cannot be overloaded, so I don't understand the outcome either.

Edit: the code I used

#include <iostream>

template<class T>
class entity
{
 private:
 int x;

public:

entity();
entity (int const& y):x(y)
{
  printf("non-template");
}
entity (T const& y): x(y)
{

}

};
int main()
{
    entity<int> en(5);
}

CodePudding user response:

A copy constructor is a non-template constructor with a certain signature. A specialization of a constructor template is never (by definition) a copy constructor.

I think "consequences" is not really used here to mean a logical implication immediately following from the previous statement. I think it is rather just meant to demonstrate some examples where the differentiation between an ordinary function and a function specialized from a function template matters.

This use of the word "consequence" seems to be a linguistic oddity. I sometimes see it used like this. It really seems to mean something more like "this allows for the following (and the following is true)".

The point here is that only declaring a copy constructor (meaning a non-template constructor) can inhibit the declaration of the implicit copy constructor. So if you only declare a constructor template that can be specialized to have the same signature as a copy constructor, there will still be an implicit copy constructor.

I don't know though what the author means with "default" in "default copy constructor". I would usually guess they just used an informal variant for "implicit", but that wouldn't make sense in the context.


In your example code there is no constructor template. The declaration of a template begins with template</*...*/> (or since C 20 as a function with auto placeholders in parameter types).

entity (T const& y): x(y)
{

}

This is just an ordinary non-template constructor. It's parameter type does depend on the template parameter of the class, but that doesn't make it itself a template (although a templated entity). Even setting that aside, if you specialize the class for e.g. entity<int>, then the parameter becomes type int const&, not entitiy<int> const&, so it won't have the signature of a copy constructor at all. The compiler complains about impossible overload because there is already another constructor with exactly the same parameter list and both are non-template constructors.

A constructor template would be e.g.:

template<typename U>
entity (U const& y): x(y)
{

}

and this one would not inhibit the implicit declaration and definition of the implicit copy constructor although it can be specialized to entity(entity<T> const&) for U = entity<T>. Overload resolution will then still choose the implicit copy constructor instead of this constructor template to perform copies.

  • Related