My question is how to make lifetime extension work with CRTP. For example, the following code is perfectly valid:
struct A {
const int& ref;
};
struct B {
const A& a;
};
int main() {
B b{{123}};
return b.a.ref;
}
Its CRTPed version is not:
template <class DerivedT>
class Gettable {
public:
int Get() const {
return static_cast<const DerivedT*>(this)->GetImpl();
}
};
class A : public Gettable<A> {
friend class Gettable<A>;
public:
A(int r) : ref{r}{}
private:
int GetImpl() const {
return ref;
}
const int& ref;
};
template <class T>
class B {
public:
B(const Gettable<T>& gettable) : get_{gettable}{}
int DifferentGet() const {
return get_.Get();
}
private:
const Gettable<T>& get_;
};
int main() {
B b{A{123}};
return b.DifferentGet();
}
The problem is that the original A
and its Gettable<A>
subobject only exist till the the of B
constructor.
I have two questions:
1) Why? It is in no way different from the first case of structs, every lifetime is known at compile time, so I believe that compiler should be able to extend lifetime of all temporaries.
2) Is there any good way to overcome this issue?