每个附加条件

时间:2013-09-13 05:33:13

标签: c++ c++11

我想知道:是否有可能为每个添加额外条件? 我在想类似的事情:

int i=0;
for(auto &it : list; i++)
    if(it.ID == 25)
        return i;

for(auto &it : list, int i=0; i++)
    if(it.ID == 25)
        return i;

3 个答案:

答案 0 :(得分:4)

您可以使用std::find_if

const auto position = std::find_if(list.cbegin(), list.cend(), []((decltype(*list.cbegin()) value)
{
    return value.ID == 25;
});
return position - list.cbegin();

(已更新,现在独立于容器value_type)

答案 1 :(得分:1)

不,这是不可能的。您可以使用旧的“普通”for循环:

auto iter = std:begin(list)
for (int i = 0; iter != std::end(list); ++iter, ++i)
{
    auto& it = *iter;

    // ...
}

答案 2 :(得分:1)

  

强制性参考:Sean Parent's "Seasoning C++" talk

     

目标1:避免原始循环

在这些情况下,抽象你的算法!

这会更频繁地出现,因此值得将它变为通用:

#include <algorithm>

template <typename C, typename Pred>
   size_t index_if(C const& c, Pred&& pred)
{
    const auto f(begin(c)), l(end(c));

    auto match = std::find_if(f, l, std::forward<Pred>(pred));
    return (l==match) ? -1 : std::distance(f, match);
}

现在您可以编写查询:

int main()
{
    struct X { int ID; };
    const std::vector<X> v { {1},{2},{3},{25},{4},{5},{6},{42} };
    return index_if(v, [](X const& x) { return x.ID == 25; });
}

查看 Live on Coliru


PS。您可能需要基于值的版本以及基于谓词的版本:

template <typename C, typename V/* = typename C::value_type*/>
   size_t index_of(C const& c, V const v)
{
    const auto f(begin(c)), l(end(c));
    auto match = std::find(f, l, v);
    return (l==match) ? -1 : std::distance(f, match);
}