让我们来看这个简化的例子:
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++) 中,选择了 insert
的 lvalue 重载。
关于c++ - 为什么在这段代码中编译器选择 r-value ref 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25290246/