C++简洁地检查STL容器中的项目(例如向量)

JDi*_*teo 6 c++ boost stl

bool xInItems = std::find(items.begin(), items.end(), x) != items.end();
Run Code Online (Sandbox Code Playgroud)

有没有更简洁的方法来检查x是否在项目中?这似乎不必要地冗长(重复项目三次),这使得代码的意图有点难以阅读.

例如,是否有类似以下内容:

bool xInItems = boost::contains(items, x);
Run Code Online (Sandbox Code Playgroud)

如果不存在任何更简洁的boost/stl算法来检查集合是否包含项目,那么使用辅助函数启用contains(items, x)是否被认为是好的还是坏的做法?

我使用错误的STL容器吗?即使是std :: set也会导致bool xInItems = items.find(x) != items.end();看起来仍然冗长.我是否以错误的方式思考这个问题?

Mar*_*som 5

从头开始编写模板函数并不难.

template<typename T, typename Iterator>
bool contains(Iterator it1, Iterator it2, const T & value)
{
    return std::find(it1, it2, value) != it2;
}

template<typename T, typename Container>
bool contains(const Container & c, const T & value)
{
    return contains(c.begin(), c.end(), value);
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以为具有自己的find功能的容器提供特殊化,以便它不会调用std::find.

  • 为了实现上述"工业"强度:将`c.begin()`替换为`使用std :: begin;`在前一行,并且`begin(c)`并且你神奇地获得数组支持(对`做同样的事情. end()`)(C++ 11).其次,我发现返回一个指向元素的指针(或`optional`)是有用的 - 当转换为`bool`时它给出正确的值,你可以做`if(int*x = contains(vec,3) )`(我使用`optional <T&>`).添加标记支持以从序列容器中拆分关联,以使用关联容器`find`方法而不是线性搜索. (5认同)

Jer*_*fin 1

如果您的数据已排序,您可以使用std::binary_search,它返回一个bool

bool xInItems = std::binary_search(items.begin(), items.end(), x));
Run Code Online (Sandbox Code Playgroud)

如果您确实需要对项目进行未排序,但有 C++11 可用,则可以使用std::any_of,但它需要谓词,因此它最终可能至少与 一样冗长std::find(并且可能更详细)。