【发布时间】:2019-06-10 15:19:37
【问题描述】:
我的问题是如何使用 CRTP 延长生命周期。例如,以下代码完全有效:
struct A {
const int& ref;
};
struct B {
const A& a;
};
int main() {
B b{{123}};
return b.a.ref;
}
它的 CRTPed 版本不是:
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();
}
问题是原来的A 及其Gettable<A> 子对象只存在到B 构造函数之前。
我有两个问题:
1) 为什么?它与结构的第一种情况没有什么不同,每个生命周期在编译时都是已知的,所以我相信编译器应该能够延长所有临时结构的生命周期。
2) 有什么好的方法可以解决这个问题吗?
【问题讨论】:
-
通过 const-reference 延长生命周期在这个问题中得到了很好的总结,特别是在您似乎正在驾驶的情况下,
const参考类成员:Does a const reference class member prolong the life of a temporary?。我认为 CRTP 与您遇到的问题没有任何关系。在main到达b.DifferentGet()时,来自A{123}的临时地址已消失。 -
谢谢!好吧,我知道它不是特定于 CRTP,但我想问是否有任何模式(可能特定于 CRTP)可以帮助克服它。
-
您的第一个代码块无效。不幸的是(也许)C++ 中没有机制可以让您在类中存储对临时对象的引用并延长它的生命周期。
-
您实际上想要完成什么?知道我们应该能够提出适当的解决方法。
-
不,它是有效的。看看最后的例子en.cppreference.com/w/cpp/language/…
标签: c++ c++17 crtp temporary-objects