C++ 返回标准::对<;const CustomClass&;,布尔>;用于当CustomClass是抽象基类时搜索函数中的失败情况

C++ 返回标准::对<;const CustomClass&;,布尔>;用于当CustomClass是抽象基类时搜索函数中的失败情况,c++,c++11,stdmap,C++,C++11,Stdmap,我有下面一段代码,它搜索类型为std::map的映射。如果在映射中找不到项目,我想返回一个“failure”case对象 我在一个月内完成了讨论 使用std::pair和bool来指示项是否有效(注意:需要SomeResource具有适当的默认构造函数,并且构造成本不高): std::pair SomeClass::getSomething(std::string name){ std::map::iterator it=content\uux.find(名称); if(it!=content_

我有下面一段代码,它搜索类型为
std::map
的映射。如果在映射中找不到项目,我想返回一个“failure”case对象

我在一个月内完成了讨论

使用std::pair和bool来指示项是否有效(注意:需要SomeResource具有适当的默认构造函数,并且构造成本不高):

std::pair SomeClass::getSomething(std::string name){
std::map::iterator it=content\uux.find(名称);
if(it!=content_uz.end())
返回std::make_pair(*it,true);
返回std::make_pair(SomeResource(),false);
}

但是因为我的CustomClass是一个抽象基类,所以我不能实例化它

有没有更好的办法来避免这种情况?我想象返回一个指向类对象的指针可能会允许它是可变的。我想保持返回的对象不变

我的代码示例如下所示-

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);
}
std::pair NpTestMgr::find(const-UID&p\u-UID)const
{
自动搜索=m_pending.find(p_uid);
if(search!=m_pending.end())
返回std::make_pair(*search,true);
返回std::make_pair(NpBaseTest(),false);
}

有几个选项:

  • 您确实可以返回指针。要确保它是不可变的,只需返回一个
    const
    指针

  • 您可以创建一个从基类继承的特殊类,该基类不做任何事情,只发出未找到值的信号。例如:

    class NpNotFound: NpBaseTest {
        // implement pure virtual functions with dummy ones
    };
    
    然后在
    NpTestMgr::find()中执行以下操作:

    return std::make_pair(NpNotFound(), false);
    
  • 不要返回
    std::pair
    ,只需返回
    SomeClass&
    ,如果找不到值,则抛出异常。仅当您不太可能正在搜索地图中不存在的内容时,才使用此选项


您应该做C++17
std::optional
正在做的事情。它不需要任何特殊的编译器支持,因此您只需从任何支持它的库中借用实现即可。例如,libc++的铿锵版本通常很容易阅读


您最不想做的一件事是返回指针。这不是易变性的问题,而是动态内存管理。

如果返回指向常量对象的指针,则无法修改返回指针指向的对象,因为释放指针将由成员函数的用户负责?或者更确切地说,不应该释放指针的用户可能会这样做,从而导致双重释放?@ImNot,删除部分可以使用
unique\u ptr
解决。但是它对性能的影响仍然存在。如果你不介意的话,你能告诉我更多关于这些性能影响的信息吗(或者给我指一个资源,我可以从中了解返回指针的影响)。我问这个问题的原因是因为我想知道为什么“最佳实践”被认为是最好的。
std::optional
不适用于多态类型(另请参见)。@ImNot,诸如
new
delete
之类的操作有点慢,可能导致系统调用,并且是多线程应用程序中的主要惩罚
return std::make_pair(NpNotFound(), false);