Кто прав, а кто неправ, ака GCC vs Visual Studio - PullRequest
1 голос
/ 26 февраля 2011

Этот код (не "работает" правильно), но компилируется в 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;
}

В GCC я получаю следующее сообщение об ошибкеmsg:

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> > >'|

Какая команда права?VS или GCC?

1 Ответ

13 голосов
/ 26 февраля 2011

Проблема здесь:

iterator_swap(v_1.begin(),v_2.begin());

Вы передаете временную (возвращаемую из begin() функций) функции, которая принимает две неконстантные ссылки .Стандарт C ++ запрещает временным привязкам связываться с неконстантными ссылками.(Однако стандартный C ++ позволяет временным привязкам связываться с const ссылками.)

И GCC , и VC ++ (версии 2005 и более поздние) "знают" , что вы можете 't привязывает временные ссылки к неконстантным ссылкам в соответствии со стандартом C ++.Так что они оба «правы» сами по себе.Однако в Visual C ++ реализовано нестандартное расширение, которое позволяет временным привязкам связываться с неконстантными ссылками так, как вы это делаете в своем фрагменте кода.

Чтобы ловить подобные вещи, я настоятельно рекомендую вам скомпилировать свой кодс включенными предупреждениями уровня 4 (/W4) и обрабатывать предупреждения как ошибки (/WX) в Visual C ++ .Он будет ловить ошибки, подобные этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...