当前位置:  开发笔记 > 编程语言 > 正文

C++中rvalue引用(&&)的迭代器

如何解决《C++中rvalue引用(&&)的迭代器》经验,为你挑选了1个好方法。

在C++中使用Deduce类型的模板类型跟随我自己的问题,有些人提到通过iterators引用传递不是惯用的,并且在给定的用例中它不起作用:

template  iterate(Iter &first, Iter &last)
{
    // Do something with the iterators
}

iterate(container.begin(), container.end());  // error, binding non-const ref to rvalue!

更深入地发现(至少)其他两个主题涉及前者:

通过引用传递C++迭代器有什么问题?

为什么C++ STL容器的开始和结束函数按值而不是常量引用返回迭代器?

但似乎没有问题/答案,通过rvalue引用&&传递迭代器是否(甚至)比通过值传递它们更好.如在

template  iterate(Iter &&first, Iter &&last)
{
    // Do something with the iterators
}

iterate(container.begin(), container.end());

我的代码使用rvalue引用编译并运行良好,因此我对此有所了解.



1> M.M..:

首先,像你一样使用单个模板参数意味着如果传递的两个迭代器没有完全相同的类型,模板推导将失败(和相同的值类别,因为这是转发引用).

例如这段代码:

template  
size_t count(Iter &&first, Iter &&last) { ...... }

// ...

std::string s("hello");
auto s_it = s.begin();
count(s_it, s.end());

实际上编译失败,因为它不知道是否要演绎Iterstring::iterator&string::iterator.如果要传递一个const_iterator和一个非const迭代器,则会出现类似的问题.


您可以使用两个模板参数来解决此问题.但后来我们开始遇到逻辑错误.

迭代器按值传递是惯用的,因此如果迭代器突然通过引用传递,它可能会让人感到惊讶(因此会引入错误).

例如:

template  
size_t count(It1 &&first, It2 &&last)
{
    size_t c = 0;

    while ( first != last )
        ++first, ++c;

    return c;
}

int main()
{
    std::string s("hello");

    auto s_it = s.begin();
    std::cout << count(s_it, s.end()) << ' ';
    std::cout << *s_it << '\n';
}

编码器希望在5 h这里输出,但事实上代码将取消引用结束迭代器,因为你通过s_it引用传递并且函数修改了它.

当然,count可以通过拍摄副本来避免这种情况first......但是现在你浪费了时间和记忆,而不是仅仅通过价值传递.

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有