0

Example:

template<class T> class A{
  public:
    A(){}
    template<class U> A(A<U> &){}
  private:
    template<class U> A(A<U>&&){}
};

int main() {
  A<int> a1;// legal
  A<int> a2(std::move(a1));//legal. it calls implicitly-declared constructor.
}

but when I delete A(){}:

template<class T> class A{
  public:

    template<class U> A(A<U> &){}
  private:
    template<class U> A(A<U>&&){}
};

int main() {
  A<int> a1;// illegal. 3
  A<int> a2(std::move(a1));
}

  • If template constructors don't influence implicitly-declared-rules. why does it become illegal?
  • If template constructors do influence implicitly-declared-rules, why isn't A<int> a2(std::move(a1)); illegal in the first example?

Tested in gcc and clang on ubuntu.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Long
  • 155
  • 1
  • 4

1 Answers1

4

In

template<class T> class A{
  public:
    A(){} // A
    template<class U> A(A<U> &){} // B
  private:
    template<class U> A(A<U>&&){} // C
};

int main() {
  A<int> a1; // 1
  A<int> a2(std::move(a1)); // 2
}

line 1 calls constructor A. Line 2 however doesn't call constructor A, B, or C. Since your class does not declare a copy constructor (B is not a copy constructor because it is a template) the compiler creates a default move constructor (C is not a move constructor because it is a template) and it is that default move constructor that line 2 uses.

In you second example, the presence of B and C stops the compiler from generating a default constructor so line 1 no longer compiles, but if it did, line 2 would still compile because it would use the compiler generated move constructor.


So, the rule here that is tripping you up is a copy or move constructor is never a template constructor, but constructor templates still count as constructors, so they disable the default constructor. That means you need to ignore them when checking to see if your class will have a default copy or move constructor generated. For the rules on when you get which see: Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
NathanOliver
  • 171,901
  • 28
  • 288
  • 402