c++ - 为什么在这段代码中编译器选择 r-value ref 版本

标签 c++ c++11 vector

让我们来看这个简化的例子:

std::vector< int > v;
v.push_back( 1 );
v.insert( v.end()-1, v[ v.size()-1 ] ); // the problem is on this line

// We output the vector
std::for_each( v.begin(), v.end(), []( const int& e_ ){ std::cout<<e_<<std::endl; } );

输出:

-17891602
1

代码的作者打算在 vector 末尾之前插入最后一个元素的拷贝。有几种很好的方法可以做到这一点,但作者决定使用这种方法。

它在 C++11 之前按“预期”工作。这是因为在 vector 中插入的 Microsoft 实现中,它们会复制要插入的值,以防插入的值在 vector 的范围内。

现在使用 C++11,有一个采用 r 值引用的插入版本,它不需要执行此技巧,因为它无论如何都是临时的。

但令人惊讶的是,使用上面的代码,编译器决定采用 r-value ref 版本而不是 by-reference 版本,后者会在 vector 末尾之前插入一个未初始化的值。请注意,operator[] 通过引用返回。

为什么编译器选择通过右值引用获取版本?

最佳答案

听起来您可能在 vector 实现中或在您自己的代码中遇到了错误。但是,我没有在您发布的内容中看到错误。这是您的帖子的完整示例:

#include <iostream>
#include <vector>

template <class Iter>
void
display(Iter first, Iter last)
{
    std::cout << "{";
    if (first != last)
    {
        std::cout << *first;
        for (++first; first != last; ++first)
            std::cout << ", " << *first;
    }
    std::cout << "}\n";
}

template <class C>
void
display(const C& c)
{
    display(c.begin(), c.end());
}

int
main()
{
    std::vector< int > v;
    v.push_back( 1 );
    v.insert( v.end()-1, v[ v.size()-1 ] );
    display(v);
}

对我来说输出:

{1, 1}

也就是说,在我使用的实现 (libc++) 中,选择了 insertlvalue 重载。

关于c++ - 为什么在这段代码中编译器选择 r-value ref 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25290246/

相关文章:

c++ - 嵌套模板的模板模板别名?

c++ - 如何在 C++ 中创建通用 stringToVector 函数?

c++ - 绝对安全的静态/运行时数字转换

c++ - 如何在 C++11 中插入 std::map ?

c++ 模板类无法修复 ostream 和 istream 函数

c++ - 具有不同模板的派生类对象的 vector

c++ - 假设我有赋值运算符,我的复制构造函数是 this = obj 好吗?

c++ - 将文本文件单词插入 AVL

c++ - 可变参数模板和 std::array 意外行为

c++ - vector 中字符串的内存分配