C++ 为什么std::map没有FindOrNull方法

C++ 为什么std::map没有FindOrNull方法,c++,C++,FindOrNull比内置的find更简洁。比较 auto& map = GetMap() if (auto iter = map.find("key"); iter != map.end()) { // use iter.second } 与 您的提案没有准确区分“未找到”和“找到null/false/0的值”。当前C++通过与容器.Enter()进行区分,你需要某种方式获取信息。 以数据库为例,我们需要“null”与任何实际值完全不同。在这里,

FindOrNull比内置的find更简洁。比较

    auto& map = GetMap()
    if (auto iter = map.find("key"); iter != map.end()) {
       // use iter.second
    }


您的提案没有准确区分“未找到”和“找到null/false/0的值”。当前C++通过与容器.Enter()进行区分,你需要某种方式获取信息。

以数据库为例,我们需要“null”与任何实际值完全不同。在这里,您似乎将其等同于false、nullptr或0。所有这些都是必须实现此接口的某些容器中的有效值

通过python中的一些示例,“notfound”选项是一个例外。这在python中很容易处理,因为该语言牺牲了性能,使异常相对容易处理。但是用C++中的异常处理它的性能要差得多,而且从语法清晰度的观点来看也更差。


您的建议更接近于提供默认值(例如false、0、nullptr)的getter。您会丢失有关是否在容器中找到它的信息,但并不总是需要这些信息。这是您可以在类中实现的,但是您想要求对标准库中的所有容器都实现它吗?这就是这里的问题。

首先
std::map
可以包含任何内容。它可以是一个指针(然后
null
有意义,但它包含一个值,然后
null
就没有意义了)

要解决此问题,您可以使用助手:

模板
自动获取可选值(T&&map、K&&key)
{
autoit=map.find(std::forward(key));
if(it==map.end())返回std::optional{};
返回std::可选{it->second};
}


请注意,
std::optional
对于c++17来说非常新鲜。

我想您是在问为什么STL不提供函数

template<class K, class V>
V* map<K,V>::find_or_null(const K& key) {
    auto it = find(key);
    if(it)
         return &it->second;
    else
         return nullptr;
}
模板
V*map::find_或_null(常量K和键){
自动it=查找(键);
如果(它)
返回&it->second;
其他的
返回空ptr;
}
关于标准库为什么会做某些事情的问题,通常会有一个答案不能让您满意。做某事总是有多种方法,标准库会选择一种。我个人认为你提议的职能没有多大必要。与查找方式相比,它节省不了太多,并且会丢失键上的信息。请注意,映射中的键仅与查找的键等效,不一定相等。所以这个信息很有趣


如果您想将其与库中的函数进行比较(
std::get_If
用于变体,而
std::any_cast
用于
std::any*
),您会发现这样做是有原因的。如果不提前检查,这些是访问这些容器而不可能抛出的唯一方法。对于map,您已经在find中找到了它,它返回一个非常类似于指针的iterstor,只包含额外的信息。

因为它可以包含不能表示为null的值。您希望
null
对象是什么,默认构造的对象?如果地图真的包含这样一个对象,这将产生歧义。你应该提出它。现在我们有了<代码> STD::可选的。这是一个不错的补充。C++没有“null”值。用户定义结构的“null”值是什么?您的意思是,返回一个迭代器,可以像
it==null
?这就限制了迭代器必须与integer和
std::nullptr__t
相比较,这将使实现更加困难。现在我们已经有了
std::optional
,问题变成了“为什么
std::map
不提供
find()
返回
std::可选
”的成员?
template<class K, class V>
V* map<K,V>::find_or_null(const K& key) {
    auto it = find(key);
    if(it)
         return &it->second;
    else
         return nullptr;
}