When running the following code on gcc 8 (https://wandbox.org/, with "g++ prog.cc -Wall -Wextra -std=c++1z"):
#include <iostream>
class B{
public:
B(): copy(false){ std::cout << "B-constructed" << std::endl;}
B(const B& b): copy(true){ std::cout << "B-copy-constructed" << std::endl; }
~B(){ std::cout << (copy?"B-destructed":"B-(copy)-destructed") << std::endl;}
bool copy;
};
class A{
public:
A(B b): bref(b){std::cout << "A-constructed" << std::endl;}
~A() {std::cout << "A-destructed" << std::endl;}
B &bref;
};
void f(){
B b;
A a(b);
std::cout << "f over" << std::endl;
}
int main()
{
f();
std::cout << "main over" << std::endl;
return 0;
}
the following output is yielded:
B-constructed
B-copy-constructed
A-constructed
B-destructed
f over
A-destructed
B-(copy)-destructed
main over
The order of object destructions seems unusual. It is as if the lifetime of the constructor's parameter is extended. Does the standard say anything about binding member references to constructor parameters?
I don't think that this quote from the standard applies, as the parameter is not a temporary object (however I do not know the definition of a "temporary expression"):
A temporary expression bound to a reference member in a mem-initializer is ill-formed. [ Example:
struct A {
A() : v(42) { } // error
const int& v;
};
—end example ]