【发布时间】:2021-10-22 19:01:42
【问题描述】:
我有一个CRTP 模板,我在其中使用了一个对象池。使用 generate() 静态方法分配对象。
template <class tDerivedSignal, class tBridgeType, class tPayLoadType = void>
class SignalT : public SignalSignatureT<tBridgeType>
{
...
static tDerivedSignal &generate(tPayLoadType &fPayLoad)
{
tDerivedSignal &rtnVal = Pool::reserve();
// Copy pay load to signal instance
rtnVal.mPayLoad = fPayLoad;
// Return generated signal
return(rtnVal);
}
...
}
现在,问题是我不想阻止像这样的复制分配
DerivedSignal sig = DerivedSignal::generate()
原因是副本 sig 可能具有本地范围并变得无效/被破坏,这将在以后用户尝试使用它时产生段错误.此外,分配的池对象将丢失并泄漏内存。我希望上面的复制分配生成编译时错误,但引用分配例如
DerivedSignal &sig = DerivedSignal::generate()
应该没问题。我试图删除 CRTP 模板中的赋值运算符,但没有成功:
template <class tDerivedSignal, class tBridgeType, class tPayLoadType = void>
class SignalT : public SignalSignatureT<tBridgeType>
{
...
// Disable copy assignment operator to prevent a generated signal from being copied into
// a new instance that is not under pool management
tDerivedSignal operator=(const tDerivedSignal &) = delete;
tDerivedSignal operator=(const tDerivedSignal) = delete;
...
}
有人知道吗?
【问题讨论】:
-
不是赋值,是复制构造。你想要
tDerivedSignal(const tDerivedSignal&) = delete; -
我最初的想法相同,但在 GCC 4.7 上无法编译。我在“const”之前得到“预期的不合格 ID”
-
哦,抱歉,被代码中的某些东西弄糊涂了,复制构造(以及通常的复制赋值)是在当前类型上完成的,所以你只需要
SignalT(cont SignalT) = delete -
您不应该忽略您使用 GCC 4.7。它对 C++11 的支持仍处于试验阶段。我们提供的有效 C++11 建议可能不起作用。
-
这也是不行的,因为(我相信)复制构造删除仅适用于 SignatT 类型而不适用于派生类型。如果我这样做 DerivedSignal(const DerivedSignal&) = delete;它可以工作,但这样会使模板的目的无效。