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

nod*_*kai 2 c++ algorithm dictionary iterator stl

Python允许您编写if e in arr: ... if key in dict: ...这很方便。

我们可以使用std::find()和与后者做类似的事情std::map吗?这将使我能够统一处理std::arraystd::map使用一个通用函数,而无需显式切换到std::map::find()

但是,如果过载operator==()是唯一的方法,我宁愿放弃这个主意...

更新:请注意我已经有一种解决方案

“超载operator==()”的意思是这样的:

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
}
Run Code Online (Sandbox Code Playgroud)

当我们K以通用方式处理非标量(完美转发?)时,事情会变得更加复杂

Vit*_*meo 5

...为什么不编写自己的效用函数?

template <typename TContainer, typename TValue>
bool contains(const TContainer& c, const TValue& x);
Run Code Online (Sandbox Code Playgroud)

您可以使用重载来匹配容器:

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);
}
Run Code Online (Sandbox Code Playgroud)

用法:

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));
Run Code Online (Sandbox Code Playgroud)

魔盒上的现场示例


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

检测成语很可能使它很容易通过SFINAE检查成员的出勤情况(和它的实现是C ++ 11兼容)

我还写了一篇有关使用C ++ 17原位检查表达式有效性的文章,这可能是一个有趣的文章。尽管标题如此,但它涵盖了用于检查表达式有效性的C ++ 11,C ++ 14和C ++ 17技术:

“使用C ++ 17就地检查表达式的有效性”