使用boost::optional时避免使用temporary
Avoiding temporary when using boost::optional
boost::可选支持in_place结构,如下所示:
#include <boost/optional.hpp>
#include <boost/utility/typed_in_place_factory.hpp>
class Foo
{
int a,b;
public:
Foo(int one, int two) : a(one),b(two) {}
};
int main()
{
boost::optional<Foo> fooOpt(boost::in_place<Foo>(1,3));
}
一旦我们有一个初始化的fooOpt,有没有办法分配一个新的Foo给它而不创建一个临时的?
例如:
fooOpt = boost::in_place<Foo>(1,3);
谢谢!
boost::optional
#include <boost/optional.hpp>
int main() {
boost::optional<int> x;
x = boost::in_place(3);
}
我们还可以(通过代码)通过使Foo
继承boost::noncopyable
来显示这是在原位构建对象:
#include <boost/optional.hpp>
#include <boost/noncopyable.hpp>
class Foo : boost::noncopyable {
public:
Foo(int one, int two) {}
};
int main() {
boost::optional<Foo> x;
x = boost::in_place(3, 4);
}
std::可选(最终…)
最终,我们将获得std::optional
。此类型将实现emplace()
方法,该方法也将实现就地构建。
#include <optional>
int main() {
std::optional<int> x;
x.emplace(3);
}
boost::可选(很快…)
在1.56.0版本中,boost::optional
也将实现我在std::optional中提到的emplace()
方法。我们看一下:
#include <boost/optional.hpp>
int main() {
boost::optional<int> x;
x.emplace(3);
}
文档中的接口不支持此操作
然而,如果你知道没有人扩展boost::optional
,我相信这可能在技术上是有效的:
template<typename T, typename... Us>
void emplace_replace( boost::optional<T>& target, Us&&... us ) {
target.~boost::optional<T>();
try {
new (&target) boost::optional<T>( boost::in_place( std::forward<Us>(us)...) );
} catch(...) {
new (&target) boost::optional<T>();
throw;
}
}
在这里,我们破坏target
,然后用原位构造在其位置上重建一个新的boost::optional<T>
。try
- catch
构造应该使构造期间的大多数throw
s是安全的:如果它抛出,你最终得到一个空的optional
。
这自然与operator=
的预期行为不同。
在1.55(可能更早?)中,有一个未记录的operator=
,它接受一个支持boost::in_place
和boost::in_place<T>
的Expr
。
我的快速阅读表明,通过此方法键入的就地工厂可能没有足够的保护:
boost::optional<int> test;
// test = boost::in_place<double>( 3 ); // <-- very dangerous
test = boost::in_place( 3 ); // safe
test = boost::in_place( 3.0 ); // safe
如果一个类型直接传递给in_place<?>
,它可能会生成一个typed_in_place_factory
,这是危险的(它们使传入的类型,而不检查它是否兼容)。所以不要将任何类型传递给boost::in_place
。
这(从阅读源代码)做了一些类似于我的destroy/rebuild代码,除了它没有破坏整个optional
,只是破坏存储的数据,使其未初始化。
在boost 1.56b1中,放置被添加到boost::optional
。它所做的事情类似于上述两个操作。(通过@AkiraTakahashi)
我看到的std::optional
提案包含了一个成员函数.emplace( Us&&... )
,它支持直接替换位置
一旦你知道它在那里,你就可以创建一个普通的引用:
optional<Foo> optFoo = ....;
Foo &foo = *optFoo;
foo.x = 3;
foofun(foo);
foo = Foo();
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 使用Boost Interprocess创建托管共享内存需要很长时间
- Boost::posix_time::ptime舍入到给定的分钟数
- 使用boost::optional时避免使用temporary