谁是对的,谁是错的又名GCC vs Visual Studio

The*_* do 1 c++ gcc visual-studio-2010 visual-c++

此代码(不能"正常"工作)但在VS 2010中编译但不会在GCC 4.5.1中编译

#include <iostream>
#include <vector>//not necessary second > should skip like brackets

using namespace std;

template<class ForwardIterator>
void iterator_swap(ForwardIterator& left,ForwardIterator& right)
{
    typename ForwardIterator::value_type tmp = *left;
    *left = *right;
    *right = tmp;
}

template<class T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& obj)
{
   typename std::vector<T>::const_iterator beg = obj.cbegin();
   typename std::vector<T>::const_iterator end = obj.cend();
    while (beg != end)
    {
        out << *beg << '\n';
        ++beg;
    }
    return out;
}

int main()
{
    vector<unsigned> v_1;
    for (vector<unsigned>::size_type i = 0; i < 10; ++i)
    {
        v_1.push_back(i);
    }
    vector<unsigned> v_2;
    for (vector<unsigned>::size_type i = 0; i < 10; ++i)
    {
        v_2.push_back(i*10);
    }
    cout << "v_1:\n" << v_1;
    cout << "v_2:\n" << v_2;
    iterator_swap(v_1.begin(),v_2.begin());
    cout << "After swap:\n";
    cout << "v_1:\n" << v_1;
    cout << "v_2:\n" << v_2;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在海湾合作委员会,我得到了以下错误信息:

E:\CodeBlocks\Iter_swap\main.cpp|41|error: 
     invalid initialization of non-const reference of type     
       '__gnu_cxx::__normal_iterator<unsigned int*, std::vector<unsigned int, 
           std::allocator<unsigned int> > >&' from a temporary of type 
       '__gnu_cxx::__normal_iterator<unsigned int*, std::vector<unsigned int, 
           std::allocator<unsigned int> > >'|
Run Code Online (Sandbox Code Playgroud)

那么哪支球队是对的?VS或GCC?

In *_*ico 13

问题出在这里:

iterator_swap(v_1.begin(),v_2.begin());
Run Code Online (Sandbox Code Playgroud)

您将临时(从begin()函数返回)传递给接受两个非const引用的函数.标准C++禁止临时绑定到非const引用.(但是,标准C++确实允许temporaries绑定到const引用.)

GCC 和VC++(版本2005及更高版本)都"知道"您无法根据标准C++将临时对象绑定到非const引用.所以他们本身都是"正确的".但是,Visual C++实现了一个非标准扩展,允许临时文件以您在代码片段中的方式绑定到非const引用.

为了捕获这样的东西,我强烈建议您使用level(4)警告启用(/W4)/WX编译代码,在Visual C++上将警告视为错误().它会捕获这些错误.

  • +1所以真的,答案是"不,你没有用'/ W4`编译你错了". (6认同)
  • @There我们无能为力:`/ W4`的文档指出["对于一个新项目,最好在所有编译中使用/ W4"](http://msdn.microsoft.com/en-我们/库/ thxezb7y.aspx).不以最高警告级别本身编译不是编译错误,但建议您在编译时捕获与编译器一样多的错误.在编译时而不是运行时捕获错误总是一件好事. (6认同)
  • @There:没有用/ W4编译然后问这里有什么问题是错误的,当4级警告告诉你的时候. (5认同)
  • @There:当你发现自己提出这样的问题时,如果没有启用所有警告就编译成错误.有证据表明你可能试图超越编译器或编写过多的代码来测试规范的边缘情况.我可能只是一个简单的专家,但我是一个用`/ W4`编译的人. (3认同)
  • @There我们无能为力:如果我们真的想要聪明地评估它,那么就标准而言,使用不合格的编译器编译C++是一个"错误".期望两个不合格的编译器做同样的事情,或者如果他们不这样做,那么其中一个必须是"错误的",这自然是一个错误.GCC和MSVC默认都是*故意*不符合.如果你把它们放到各自严格的模式中,那么它们就到目前为止一直在遵守,受到各自作者的聪明才智的限制. (3认同)