【发布时间】:2014-04-23 12:25:17
【问题描述】:
如果我有两个类 D1 和 D2 都派生自类 Base,并且我想基于一个布尔变量构建一个特定的类,那么有各种众所周知的技术,例如使用工厂或使用智能指针.
例如,
std::unique_ptr<Base> b;
if (flag)
{
b.reset(new D1());
}
else
{
b.reset(new D2());
}
但这使用堆进行分配,这通常很好,但我可以想到避免内存分配的性能影响的时候。
我试过了:
Base b = flag ? D1() : D2(); // doesn’t compile
Base& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? std::move(D1()) : std::move(D2()); // doesn’t compile
我的意图是选择的 D1 或 D2 在堆栈上构建,并且当 b 超出范围时其生命周期结束。直觉上,我觉得应该有办法做到这一点。
我玩过 lambda 函数,发现这行得通:
Base&& b = [j]()->Base&&{
switch (j)
{
case 0:
return std::move(D1());
default:
return std::move(D2());
}
}();
我不知道为什么它不会遇到与其他不编译的问题相同的问题。 此外,它仅适用于复制成本较低的类,因为尽管我明确要求使用移动,但我认为它仍然调用复制构造函数。但如果我拿走 std::move,我会收到警告!
我觉得这更接近我认为应该可能的,但它仍然存在一些问题:
- lambda 语法对还没学过的老手不友好 接受了语言的新特性(包括我自己)
- 前面提到的复制构造函数调用
有更好的方法吗?
【问题讨论】:
-
std::move只是一个演员表。它实际上并没有移动任何东西。你最终会得到一个悬空引用。 -
你不能只构造类对象。
标签: c++11 lambda stack allocation lifetime