[英]How to rewrite with boost::optional in C++11?
如何在 C++11 中重写以下代码以使用boost::optional
或boost::none
?
std::unique_ptr<FooBase> find( std::string key)
{
std::map<std::string, std::function<std::unique_ptr<FooBase>(void)> > m{
{"key1", [](){return std::make_unique<BarDerived>();} },
{"key2", [](){return std::make_unique<BarDerived1>();} } };
auto it = m.find(key);
if (it != std::end(m))
return (it->second());
else
return nullptr;
}
那么,您希望它返回一个值类型而不是一个指针吗?
由于对象切片, boost::optional
(或c++17 中的std::optional
)不可能做到这一点。 对于值类型,您只能返回与FooBase
包含的信息一样多的信息,因此当您从派生类型之一向上转换时,您将丢失信息。
不过,为此,您可以使用 C++17 标准采用的另一种 Boost 类型: boost::variant
。 这是一个类型安全的标记联合,可以在同一内存空间中保存一组类型中的一个。 只需添加一个类型来表示“无”(C++17 中std::monostate
的目的,Boost 中boost::blank
的目的),然后添加每个派生类型:
struct Bar1 { };
struct Bar2 { };
using Bar = boost::variant<boost::blank, Bar1, Bar2>;
然后你可以像这样重写你的函数:
Bar find( std::string key)
{
std::map<std::string, std::function<Bar()> > m {
{"key1", [](){return Bar1 {}; } },
{"key2", [](){return Bar2 {}; } }
};
auto it = m.find(key);
if (it != std::end(m))
return (it->second());
else
return { }; // default-constructs the first variant, in this case blank
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.