Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;STL:std::使用std::map查找_C++_Algorithm_Dictionary_Stl_Iterator - Fatal编程技术网

C++ C++;STL:std::使用std::map查找

C++ C++;STL:std::使用std::map查找,c++,algorithm,dictionary,stl,iterator,C++,Algorithm,Dictionary,Stl,Iterator,Python允许您在arr:…中编写,如果键入dict:…则编写,这很方便 我们可以使用std::find()和std::map对后者执行类似的操作吗?这将允许我使用单个通用函数统一处理std::array和std::map,而无需显式切换到std::map::find() 但是如果重载操作符==()是唯一的方法,我宁愿放弃这个想法 更新:注意,我已经有了一种解决方案 “重载操作符==()”我的意思是这样的: template<typename K> struct KF {

Python允许您在arr:…中编写
,如果键入dict:…
则编写
,这很方便

我们可以使用
std::find()
std::map
对后者执行类似的操作吗?这将允许我使用单个通用函数统一处理
std::array
std::map
,而无需显式切换到
std::map::find()

但是如果重载
操作符==()
是唯一的方法,我宁愿放弃这个想法

更新:注意,我已经有了一种解决方案 “重载
操作符==()
”我的意思是这样的:

template<typename K>
struct KF {
    K&& k;

    template <typename V>
    friend bool operator==(const typename std::pair<const K, V>& pair, const KF<K>& o) {
        return pair.first == o.k;
    }

};

template <typename K>
KF<K> keyFinder(K&& k) { return KF<K>{ std::forward<K>(k) }; }

int main() {
    std::set<int> s{ 1, 2, };
    cout << (std::find(s.begin(), s.end(), 1) == s.end()) << endl; // => 0
    cout << (std::find(s.begin(), s.end(), 3) == s.end()) << endl; // => 1

    std::map<int, int> m{ {1,10}, {2,20}, };
    cout << (std::find(m.begin(), m.end(), keyFinder(1)) == m.end()) << endl; // => 0
    cout << (std::find(m.begin(), m.end(), keyFinder(3)) == m.end()) << endl; // => 1
}
模板
结构KF{
K&&K;
模板
friend bool运算符==(常数类型名称std::pair&pair,常数KF&o){
返回pair.first==o.k;
}
};
模板
KF键查找器(K&&K){返回KF{std::forward(K)};}
int main(){
std::集s{1,2,};

cout…为什么不编写自己的实用函数呢

template <typename TContainer, typename TValue>
bool contains(const TContainer& c, const TValue& x);
模板
bool包含(常量TContainer&c、常量TValue&x);
您可以使用重载来匹配容器:

template <typename TValue, std::size_t N>
bool contains(const std::array<TValue, N>& c, const TValue& x)
{
    return std::find(std::begin(c), std::end(c), x) != std::end(c);
}

template <typename TValue, typename... Ts>
bool contains(const std::map<Ts...>& c, const TValue& x)
{
    return c.find(x) != std::end(c);
}
模板
布尔包含(常量std::数组和c、常量TValue和x)
{
返回std::find(std::begin(c),std::end(c),x)!=std::end(c);
}
模板
布尔包含(常量std::map&c、常量TValue&x)
{
返回c.find(x)!=std::end(c);
}
用法:

std::array<int, 2> a{1,2};
std::map<int, int> b{{1,2},{3,4}};

assert(contains(a, 1));
assert(!contains(a, 42));
assert(contains(b, 1));
assert(!contains(b, 42));
std::数组a{1,2}; 映射b{{1,2},{3,4}; 断言(包含(a,1)); 断言(!包含(a,42)); 断言(包含(b,1)); 断言(!contains(b,42));


如果您想在将来支持其他容器,最好使用SFINAE检查特定表达式是否有效。这种方法效果很好,因为它不关心容器的类型,只关心可以对其执行哪些操作

这可能会使通过SFINAE检查成员可用性变得非常容易(其实现与C++11兼容)

我还写了一篇关于使用C++17现场检查表达式有效性的文章,这可能是一篇有趣的阅读。尽管它的标题是C++11、C++14和C++17检查表达式有效性的技术:


要回答您明确的问题-不,
std::find
将无法统一用于
std::map
/
std::unordered_map
std::array
/
std::vector
,因为前者是键/值对的集合,后者是值的集合

您可能希望改用
std::find_if
,因为它在定义相等条件方面给您提供了更多的灵活性,例如(c++1z方法):

#包括


请记住,如果您决定像
std::vector

这样搜索集合,这种方法将不会像预期的那样工作。这就是我所说的“显式切换到
std::map::find()
”的意思…如果我想支持
无序映射
多映射
,以及像
spp::稀疏散列映射
这样的第三方库,该怎么办?检查SFINAE是否有
M::find
。@nodakai:这可能会起作用-这可能会使通过SFINAE检查成员可用性变得非常容易(而且它的实现与C++11兼容)。@nodakai:我在我的回答中添加了关于SFINAE方法的更多信息-如果您有更多问题,请告诉我。
#include <array>
#include <map>
#include <string>
#include <algorithm>
#include <type_traits>

template <class T>
struct is_pair: std::false_type { };

template <class K, class V>
struct is_pair<std::pair<K,V>>: std::true_type { };

int main() {
    std::map<std::string, int> m {{"abc", 1}, {"cde", 2}, {"efg", 3}};
    std::array<int, 5> a{1, 2, 3, 4, 5};

    auto lambda = [](auto it) {
        if constexpr (is_pair<decltype(it)>::value) {
            return it.second == 3;
        } else {
            return it == 3;
        }
    };

    assert(std::find_if(a.begin(), a.end(), lambda) != a.end());
    assert(std::find_if(m.begin(), m.end(), lambda) != m.end());
}