Templated copy-constructor fails with specific templated type

强颜欢笑 提交于 2019-11-29 06:46:55

It fails because a template doesn't suppress the implicit declaration of a copy constructor. It will serve as a simple converting constructor, which can be used to copy an object when overload resolution selects it.

Now, you probably copied your matrix somewhere, which would use the implicitly defined copy constructor which does a flat copy. Then, the copied matrix and the copy would both in their destructor delete the same pointer.

Furthermore, why is the extremely verbose template <typename T> template <typename U> syntax required

Because there are two templates involved: The Matrix, which is a class template, and the converting constructor template. Each template deserves its own template clause with its own parameters.

You should get rid of the <T> in your first line, by the way. Such a thing does not appear when defining a template.

This is a poor solution, as it results in the wholesale duplication of the copy-constructor code

You can define a member function template, which will do the work, and delegate from both the converting constructor and the copy constructor. That way, the code is not duplicated.


Richard made a good point in the comments which made me amend my answer. If the candidate function generated from the template is a better match than the implicitly declared copy constructor, then the template "wins", and it will be called. Here are two common examples:

struct A {
  template<typename T>
  A(T&) { std::cout << "A(T&)"; }
  A() { }
};

int main() {
  A a;
  A b(a); // template wins:
          //   A<A>(A&)  -- specialization
          //   A(A const&); -- implicit copy constructor
          // (prefer less qualification)

  A const a1;
  A b1(a1); // implicit copy constructor wins: 
            //   A(A const&) -- specialization
            //   A(A const&) -- implicit copy constructor
            // (prefer non-template)
}

A copy constructor can have a non-const reference parameter too, if any of its members has

struct B { B(B&) { } B() { } };
struct A {
  template<typename T>
  A(T&) { std::cout << "A(T&)"; }
  A() { }
  B b;
};

int main() {
  A a;
  A b(a); // implicit copy constructor wins:
          //   A<A>(A&)  -- specialization
          //   A(A&); -- implicit copy constructor
          // (prefer non-template)

  A const a1;
  A b1(a1); // template wins: 
            //   A(A const&) -- specialization
            // (implicit copy constructor not viable)
}

I'm not entirely clear from your question, but I suspect what is happening is that the default copy constructor (which does a memberwise copy only) is being used in some places in your code. Remember, not only the code you actually write uses the copy constructor - the compiler uses it too.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!