forward_iterator模板类是否有意义?

时间:2015-10-14 10:21:03

标签: c++ c++11 iterator c++-standard-library

C ++标准库包含方便的模板类std::move_iterator。鉴于std::movestd::forward之间的密切关系,为什么没有等效的std::forward_iterator?用法示例:

template <typename C>
auto foo(C&& values)
{
    remove_reference_t<C> result {};
    result.reserve(values.size());
    std::transform(std::make_forward_iterator<C>(std::begin(values)),
                   std::make_forward_iterator<C>(std::end(values))), 
                   std::back_inserter(result), Bar());
    return result;
}

我现在可以使用foo这样的想法:

std::vector<ComplexType> values {/* lots of values */};

auto copied_fooed = foo(values); 
// or
auto moved_fooed  = foo(std::move(values));

无需写两个foo s。

2 个答案:

答案 0 :(得分:1)

我无法回答为什么这样的事情并不存在。但它确实可以实现。基本上,您的C类型是左值引用(在这种情况下只是通过参数)或者它不是引用(在这种情况下,使用implementation in Java)。

首先,让我们开始添加任何工具包std::make_move_iterator(稍作修改):

namespace detail {
    enum class enabler {};
}

template <bool B>
using EnableIf = std::enable_if_t<B, detail::enabler>;

现在我们只在两个重载上使用SFINAE:

template <typename C,
          typename Iterator,
          EnableIf<std::is_lvalue_reference<C>::value>...>
Iterator make_forward_iterator(Iterator i)
{
    return i;
}

template <typename C,
          typename Iterator,
          EnableIf<!std::is_lvalue_reference<C>::value>...>
auto make_forward_iterator(Iterator i)
{
    return std::make_move_iterator(i);
}

或者,这可能更简单,可以只是tag-dispatch:

namespace detail {    
    template <typename Iterator>
    Iterator make_forward_iterator(Iterator i, std::true_type )
    {
        return i;
    }

    template <typename Iterator>
    auto make_forward_iterator(Iterator i, std::false_type )
    {
        return std::make_move_iterator(i);
    }
}

template <typename C, typename Iterator>
auto make_forward_iterator(Iterator i) {
    return detail::make_forward_iterator(i, std::is_lvalue_reference<C>{});
}

答案 1 :(得分:1)

比这复杂一点。

对于拥有容器,容器的l / r值意味着移动迭代器可能是有用的。

但是对于观点,这不起作用:从右值视图移动会破坏无主状态。

实际上,这意味着基于l / r值的移动与否的决定对于相互决定的上下文和价值都是重要的,这使得它变得棘手。

Range-v3和概念可能使这更容易推理。