We should pass a derived argument object by reference to the single parameter delegated templated constructors declared in its base class.

struct base {

  public : base() {}

  template <typename T> base(T x) {}

};


struct derived : public base {

  public: derived() {}

  derived(derived& that): base(that) {}

};


int main() {

  derived d1;

  derived d2 = d1;

  return 0;

}


The assignment d2 = d1 causes derived(derived& that) to be called.

The initialzier base(that) causes the object that(which is a derived object) to be copied before template <typename T> base(T x) {} to be called, which causes derived(derived& that) to be called again.


Before passing a derived object to the single parameter templated constructor,

    the copying process for the derived object is currently underway.
The single parameter Delegated C++ constructor's copy semantics
    simply copy the portion declared in the derived object's base class.
The portion declared in the derived class do not need to be copied or constructed again.

The language's syntax is designed to express and convey the intended meaning or semantics of the code.
The rules should strike a balance between syntax and semantics to better serve the intended meaning of the code.

In the chain of constructor delegation, arguments derived from the base class should be passed by reference for the single parameter template constructor .


With the commit https://github.com/llvm/llvm-project/pull/87332 , the following code works well too.


1-2:derived2 d2(d1, hlder) causes derived2(const struct derived2& that, struct placeholder& i) to be called.

2-3:derived2(const struct derived2& that, struct placeholder& i) causes derived(const struct derived& that, struct placeholder& i) to be called.

3-4:derived(const struct derived& that, struct placeholder& i) causes derived(const struct derived& that) to be called.

4-5:derived(const struct derived& that) causes base( T x) to be called.

3-6:derived(const struct derived& that, struct placeholder& i) causes base( T x, N i).

 

struct placeholder {

};

struct base {

public:

  base(){}

  base(const base& x) {

  }

  template <typename T>

  base( T x) {//5

  }

  template <typename T, typename N>

  base( T x, N i) {

  }//6

};

struct derived : public base {

public:

  derived() {

  }

  derived(derived& that) {

  }

  derived(const struct derived& that, struct placeholder& i):base(i, that) {

  }//3-4 6

  derived(const struct derived& that):base(that) {

  }//4-5

};

struct derived2 : public derived {

public:

  derived2() {

  }

  derived2(derived2& that) {

  }

  derived2(const struct derived2& that, struct placeholder& i):derived(that, i) {

  }//2-3

  derived2(const struct derived2& that):derived(that) {

  }

};

template <typename T = double>

class sum {};


int main() {

  placeholder hlder;

  derived2 d1;

  derived2 d2(d1, hlder);//1-2

  return 0;

}