为什么在这段代码的编译器选择r值裁判版本(Why in this code the compiler

2019-10-20 16:46发布

让我们借此简化的示例:

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

代码的作者意图的载体年底前插入的最后一个元素的副本。 有几个很好的方法来此,但笔者决定使用这一个。

它的工作之前,C ++ 11的“预期”。 这是因为在微软实施的载体的插入的,它们使插入值的副本的情况下,插入的值是向量的范围。

现在用C ++ 11,有插入取R值的基准而不必做这一招,因为它是一个临时反正一个版本。

但令人惊讶的,使用上面的代码时,编译器决定采取的r值ref版本代替按引用版本,这将插入载体的结束之前一个未初始化的值。 注意,操作者[]返回参考。

为什么编译器选择采取由R值参考的版本?

Answer 1:

这听起来像你可能遇到的错误,无论是在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被选择的。



Answer 2:

原来,这是VS 2010编译器,已修复与2013编译器有问题。 我不知道那些2个版本之间的其中之一,但正是它调用使用VS2010 SP1,并与VS2013更新3 L值版本,这是预期的行为r值参考版本。

正如你可以在上面的评论看,有些人已经开始使用其他的编译器比微软的编译器测试的代码,它也按预期工作。

编辑:我发现了另外一篇关于同样的问题。 它的模板,常量和和&&组合: VISUAL C ++ 2010,右值引用错误?



文章来源: Why in this code the compiler chooses the r-value ref version
标签: c++ c++11 vector