强制转换为布尔值是检查是不是存在与键匹配的 unordered_map 值的有效方法吗? C++

Posted

技术标签:

【中文标题】强制转换为布尔值是检查是不是存在与键匹配的 unordered_map 值的有效方法吗? C++【英文标题】:Is casting to a bool a valid way to check for the existence of a unordered_map value matching a key? c++强制转换为布尔值是检查是否存在与键匹配的 unordered_map 值的有效方法吗? C++ 【发布时间】:2020-10-28 23:18:28 【问题描述】:

我有一个嵌套的 unordered_map,想检查是否为一组键创建了一个值。大多数在线解决方案如this 建议遍历密钥以检查它们的存在。正如我在下面所做的那样,尝试访问它们并将它们转换为 bool 是否存在固有问题?测试的输出让我相信它有效。

    std::unordered_map<int, std::unordered_map<int, const char*>> myMap;
    myMap[1][2]="abc";
    myMap[2][2]="false";
    std::cout <<(bool)myMap[1][2]<< std::endl;
    std::cout <<(bool)myMap[0][0]<< std::endl;
    std::cout <<(bool)myMap[0][0]<< std::endl;
    std::cout <<(bool)myMap[1][4]<< std::endl;
    std::cout <<(bool)myMap[2][2]<< std::endl;

输出

1
0
0
0
1

【问题讨论】:

如果您的测试有效,那么它有效。 它的作用是在对象不存在时创建对象,创建的std::unordered_map&lt;int, const char*&gt;的默认值为空,创建的const char*的默认值为nullptr。所以它“有效”但它改变了容器,它与实际的空值没有区别 “大多数像这样的在线解决方案都建议遍历密钥以检查它们的存在。”我在那里看到的所有解决方案都没有任何迭代。是直接访问。 map.find(k) 是 O(1)(当然假设是一个好的散列函数) 我会在代码审查中标记它以使用 C 样式转换。您的代码所做的只是检查指针是否为空。 或许您可以考虑改用std::unordered_map&lt;std::pair&lt;int, int&gt;, const char*&gt;。使用起来会更简单。 【参考方案1】:

在非常量 std::(unordered_)map 上调用 operator[] 将创建具有默认值的请求元素(如果它尚不存在),然后返回对该元素的引用。在填充 [1][2][2][2] 元素时,您正在使用该功能。

您的输出包含 0,因为您正在请求不存在的键,因此 maps 正在插入具有默认值的那些元素,因此您最终会得到一个空的 char* 指针,您将其类型转换为 @ 987654327@。任何非空值输出为true/1,任何空值输出为false/0。

要简单地检查元素是否存在,可以使用映射的find()count() 方法,或者在C++20 中使用contains() 方法,例如:

bool keysExist(
    const std::unordered_map<int, std::unordered_map<int, const char*>> &m,
    int index1, int index2)

    auto iter = m.find(index1);
    return (iter != m.end()) && (iter->find(index2) != iter->end());
    // or: return (iter != m.end()) && (iter->count(index) == 1);
    // or: return (iter != m.end()) && iter->contains(index2);


std::unordered_map<int, std::unordered_map<int, const char*>> myMap;
myMap[1][2] = "abc";
myMap[2][2] = "false";

std::cout << keysExist(myMap, 1, 2) << std::endl;
std::cout << keysExist(myMap, 0, 0) << std::endl;
std::cout << keysExist(myMap, 0, 0) << std::endl;
std::cout << keysExist(myMap, 1, 4) << std::endl;
std::cout << keysExist(myMap, 2, 2) << std::endl;

【讨论】:

可能还值得一提 count 和 (C++20) contains @RemyLebeau:它不必是全有或全无,在您的代码中 iter-&gt;find(index2) != iter-&gt;end()) 可以简化为 iter-&gt;contains(index2)

以上是关于强制转换为布尔值是检查是不是存在与键匹配的 unordered_map 值的有效方法吗? C++的主要内容,如果未能解决你的问题,请参考以下文章

强制类型转换之String类型

如何在 GCC 下强制设置“布尔”的大小

检查数组中的所有值是不是为真,然后返回一个真布尔语句(javascript)[重复]

检查至少十分之二的布尔值是真的

错误:类型不匹配:推断类型是字符串?但布尔值是预期的

数据类型的转换