Return std::pair<const CustomClass &, bool> 当 CustomClass 是一个 Abstract Base Class 时搜索函数中的失败案例

Return std::pair<const CustomClass &, bool> for failure case in a search function when CustomClass is an Abstract Base Class

我有以下一段代码,用于搜索 std::map<int, const CustomClass&> 类型的地图。如果在地图中找不到该项目,我想 return 一个 "failure" 个案例对象。

我在 Returning a “NULL reference” in C++?

中进行了讨论

Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
    std::map<std::string, SomeResource>::iterator it = content_.find(name);
    if (it != content_.end()) 
        return std::make_pair(*it, true);  
    return std::make_pair(SomeResource(), false);

}

但是因为我的 CustomClass 是一个 Abstract Base Class 我不能实例化它!

有没有更好的方法来规避这个问题?我想象 returning 一个指向 class 对象的指针可能允许它是可变的。我想保持 returned 对象不可变。

我的代码示例如下所示 -

std::pair<const NpBaseTest::NpBaseTest&, bool> NpTestMgr::find(const UID& p_uid) const
{
    auto search = m_pending.find(p_uid);
    if(search != m_pending.end())
        return std::make_pair(*search, true);
    return std::make_pair(NpBaseTest(), false);
}

有几种选择:

  • 你确实可以return一个指针。为确保它是 non-mutable,只需 return 一个 const 指针。

  • 您可以创建一个特殊的 class,它继承自基础 class,除了表示未找到值之外什么都不做。例如:

    class NpNotFound: NpBaseTest {
        // implement pure virtual functions with dummy ones
    };
    

    然后在 NpTestMgr::find() 中执行:

    return std::make_pair(NpNotFound(), false);
    
  • 而不是 returning a std::pair<SomeClass&, bool>,只是 return SomeClass&,如果找不到该值则抛出异常。仅当您不太可能搜索地图中不存在的内容时才使用此选项。

你应该做 C++17 std::optional 正在做的事情。它不需要任何特殊的编译器支持,因此您可以简单地从任何支持它的库中借用实现。例如,CLang 版本的 libc++ 通常易于阅读。

您最有可能不想做的一件事是return指针。这不是可变性的问题,而是动态内存管理。