【问题标题】:Functional versions of C++ copy_if, transform etcC++ copy_if、transform 等的功能版本
【发布时间】:2016-04-19 16:58:14
【问题描述】:

例如的非迭代器版本all_of 可以写成:

template <class Container, class UnaryPredicate>
bool all_of(Container s, UnaryPredicate f) {
  return all_of(s.begin(), s.end(), f);
}

但我认为你不能对返回容器的算法做同样的事情?

template <class Container, class UnaryPredicate>
Container copy_if(Container, UnaryPredicate);

我最接近实现的是使用向量来保存中间结果,但由于缺乏为向量提供模板参数的任何方法而绊倒了。我有什么遗漏吗?

【问题讨论】:

  • 为什么要使用vector 来保存临时结果,而不是直接使用Container
  • @Holt 因为当我尝试直接使用容器时,在 std::set 的情况下,它不起作用;编译器似乎认为 set 的迭代器是只读的,这确实有些道理。

标签: c++ stl-algorithm


【解决方案1】:

您应该使用std::insert_iterator 而不是使用vector 来保存您的临时:

template <class Container, class UnaryPredicate>
Container copy_if(Container const& input, UnaryPredicate const& up) {
    Container tmp;
    std::copy_if(input.begin(), input.end(),
                 std::insert_iterator<Container>(tmp, tmp.begin()), up);
    return tmp;
}

std::insert_iterator 需要你的容器有一个insert() 方法,这不是Container 的要求,而是SequenceContainerAssociativeContainer 的要求(表格不完整,但[associative.reqmts] 需要它(表 102))。


如果您真的想使用向量并且您的所有Container 都尊重Container 概念,那么您可以使用以下方法访问它们的值类型:

typename Container::value_type

例如:

std::vector<typename Container::value_type>

【讨论】:

    【解决方案2】:

    我认为最好的方法是采用(假设Container c)的类型:

    *std::begin(c)
    

    通过decltype

    using T = decltype(*std::begin(c));
    

    或通过自动:

    auto elem = *std::begin(c);
    

    【讨论】:

    • “你使用push_back吗?”嗯,所有容器都提供insert(),也许有可行的使用方式?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    相关资源
    最近更新 更多