繁体   English   中英

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

[英]How to rewrite with boost::optional in C++11?

如何在 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;                                        

}

那么,您希望它返回一个值类型而不是一个指针吗?

由于对象切片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
}

https://godbolt.org/z/dcYevv

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM