c++ - forward_iterator 模板类有意义吗?

标签 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

最佳答案

我无法回答为什么这样的事情不存在。但它肯定是可以实现的。基本上,您的 C 类型要么是左值引用(在这种情况下只是传递参数),要么不是引用(在这种情况下,使用 std::make_move_iterator )。

首先,让我们从任何工具包的重要补充开始,almost static if (略有改动):

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);
}

或者,这可能更简单,可以只是标记调度:

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>{});
}

关于c++ - forward_iterator 模板类有意义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33122780/

相关文章:

c++ - Poco C++ 库 : "Not found: mysql"

C++ 完美函数转发

php - 未知扩展名时检查文件是否存在

javascript - 使用 javascript/lodash 对特定键的相同值进行分组并对它们进行计数并将结果返回到数组

c++ - 即使根据容量()仍有未使用的空间,std::vector 能否将其数据移动到 emplace_back()处的另一个地址?

c++ - 如何访问和管理 block 存储的数据

c++ - 二进制字符串到十六进制 C++

c++ - 不完整类型 --> 无法从我的对象访问指针值

c++ - 我可以使用本地声明的枚举类作为模板非类型参数吗? (gcc 给出模糊的错误)

c++ - 错误代码 : how to set and check errno