I wrote the following toy example
#include <iostream>
using namespace std;
struct A {
A() { cerr << "default" << endl; }
A(const A &a) { cerr << "copy" << endl; }
A(A &&a) { cerr << "move" << endl; }
};
struct B {
A a;
};
struct C {
A a;
C(A a): a(a) {}
};
int main() {
B b {A()};
cerr << "=======" << endl;
C c {A()};
return 0;
}
Compiling and running it gives:
default
=======
default
copy
We can see that the constructor of C
creates a copy while no copy is required for the construction of B
.
I have been unable to reproduce the behavior of B
by defining my own constructor in the struct C
. Replacing C(A a): a(a) {}
by C(A a): a(forward<A>(a)) {}
creates a move for instance.
Is there any way to create a constructor that mimics the aggregate initialization of B
?
I wrote the following toy example
#include <iostream>
using namespace std;
struct A {
A() { cerr << "default" << endl; }
A(const A &a) { cerr << "copy" << endl; }
A(A &&a) { cerr << "move" << endl; }
};
struct B {
A a;
};
struct C {
A a;
C(A a): a(a) {}
};
int main() {
B b {A()};
cerr << "=======" << endl;
C c {A()};
return 0;
}
Compiling and running it gives:
default
=======
default
copy
We can see that the constructor of C
creates a copy while no copy is required for the construction of B
.
I have been unable to reproduce the behavior of B
by defining my own constructor in the struct C
. Replacing C(A a): a(a) {}
by C(A a): a(forward<A>(a)) {}
creates a move for instance.
Is there any way to create a constructor that mimics the aggregate initialization of B
?
1 Answer
Reset to default 4The usual trick here is to use a type that converts to the desired type:
struct C {
A a;
template<class T>
C(T &&t): a(std::forward<T>(t)) {}
};
struct preA {
operator A() {return {};}
};
C c(preA{});
B
doesn't have a default constructor, it is an aggregate type and aggregates have their own initialization rules. – NathanOliver Commented Jan 19 at 17:46C(A a)
. HoweverC(A a): a(a) {}
will always result copy constructor of A will be called. So probably you need to useC(A&& a)
so it will accepta
as a temporary – Pepijn Kramer Commented Jan 19 at 19:18