Is the following code legal in C++?
template<typename T>
class Foo {
public:
Foo(T& v) : v_(v) {}
private:
T& v_;
};
int a = 10;
Foo<int> f(a);
void Bar(int& a) {
new (&f)Foo<int>(a);
}
References are not supposed to be bound twice, right?
This is perfectly invalid.
[basic.life]/1, emphasis mine:
The placement new reuses the storage, ending the lifetime of the object denoted by
f
.[basic.life]/7:
Since the third bullet point is not satisfied, after a call to
Bar
,f
does not refer to the object created by the placementnew
, but to the no-longer-living object previously there, and attempting to use it results in undefined behavior.See also CWG1776 and P0137R0.
It may be legal, but it's incredibly poor style. The argument to placement new is a void*, so you're telling C++ to reinterpret_cast the address of f as a void*, then using that as the location to construct something new - overwriting the original f.
Basically, don't do that.