c++ - 如何在 C++11 中用 boost::optional 重写?
问题描述
如何在 C++11 中重写以下代码以使用boost::optional
or ?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;
}
解决方案
那么,您希望它返回值类型而不是指针吗?
由于object slicingboost::optional
,这在(或在 c++17 中)是不可能的。对于值类型,您只能返回包含的信息,因此当您从其中一种派生类型向上转换时,您将丢失信息。std::optional
FooBase
不过,为此,您可以使用另一种被 C++17 标准采用的 Boost 类型:boost::variant
. 这是一个类型安全的标记联合,可以在同一内存空间中保存一组类型中的一个。只需添加一个类型来表示“无”(std::monostate
' 在 C++17 中boost::blank
的用途和 ' 在 Boost 中的用途),然后添加每个派生类型:
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
}
推荐阅读
- android - ACRA 电子邮件发件人
- python - 时间序列的输出似乎发生了变化
- spring-batch - Spring Cloud 数据流 UI
- assembly - 如何用汇编语言中的某个数字替换 MSB 位?
- swift - Swift - 具有通用超类约束的扩展中的协议默认实现
- augmented-reality - Ar-js 和 a-frame 外观控制。如果将外观控件添加到实体,则以角度放置对象
- android - 从后台清除特定片段
- c - 我可以连续重用 pthread_t 和 pthread_attr_t 用于已执行线程的新不同线程吗?
- amazon-web-services - How to improve web-service api throughput?
- python - Python-Selenium - 使用嵌套 For 循环获取用户名和密码列表的蛮力脚本