如何在C ++ 11中使用boost :: optional进行重写?

问题描述

如何在C ++ 11中重写以下代码以使用boost::optionalboost::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。这是类型安全的tagged union,可以在同一内存空间中保存一组类型之一。只需添加一个表示“无”的类型(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
}

https://godbolt.org/z/dcYevv

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...