I have a constructor for B with some default argument depending on other arguments:
struct A
{
int f();
A(const A&) = delete;
A(A&& );
// ....
};
struct B
{
B(A a, int n=a.f()) {//...}
// ...
};
This clearly does not work in that way, so I want use a delegate constructor:
struct B
{
B(A a, int n) {//...}
B(A a): B(a, a.f()) {}
};
This, however, also does not work because the copy constructor of A is deleted. So I need something like
struct B
{
B(A a, int n) {//...}
B(A a): B(std::move(a), a.f()) {}
};
As far as I know, however, there is no guarantee that a.f() is evaluated before std::move, so the result is undefined. Is there a possiblity to get the value of a.f() before std::move or should I better write two seperate constructors?
Why don't you do something simpler - i.e. overload your constructor?
struct B
{
B(A a) {
int n = a.f();
...
}
B(A a, int n) {
...
}
};
If you don't like repetition of your code in ...
, you can always have just a single call to a private member function that does the rest of the construction.
The are more possible solutions for this.
The most simple approach is to make a
a pointer:
struct B
{
B(A* a, int n) {...}
B(A* a): B(a, a->f()) {}
};
A more complex approach is to try to make a
a reference:
struct B
{
B(A& a, int n) {...}
B(A& a): B(a, a.f()) {}
};
I would not suggest this solution. The pointer is a cleaner approach.
Edit:
Via std::move from the utility libary
struct B
{
A&& a:
int n:
B(A&& a, int n): a(std::move(a)), n(n) {...}
B(A&& a): B(std::move(a), a.f()) {...}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With