Такое использование std :: make_pair прекрасно работает в GCC 3 и 4. Не удается в Visual Studio C ++ 2010. Почему? - PullRequest
2 голосов
/ 18 сентября 2011

Это прекрасно компилируется в GCC 3 и 4. MSVC ++ не может определить тип noFunction и выдает некоторые ужасные ошибки.Обратите внимание, что если вы приведете noFunction к BFunction, она отлично работает в VS2010.

Мой вопрос: это дефект в VS2010 или GCC изгибает правила?

#include <map>

using namespace std;

typedef bool (*AFunction)(int arg1, int arg2);
typedef bool (*BFunction)(long arg1, bool arg2);

bool noFunction(long, bool) { return true; }

void test(AFunction a)
{

    make_pair(a, noFunction); //fails in VS2010

}

Приведение NB noFunction to BFunction устраняет проблему в VS2010.

make_pair(a, (BFunction)noFunction);  //works everywhere

.

.

.

Здесьэто ошибка для справки:

    1>  makepairtest.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(197): error C2752: 'std::tr1::_Remove_reference<_Ty>' : more than one partial specialization matches the template argument list
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(356): could be 'std::tr1::_Remove_reference<_Ty&&>'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(350): or       'std::tr1::_Remove_reference<_Ty&>'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(962) : see reference to class template instantiation 'std::tr1::remove_reference<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(26) : see reference to class template instantiation 'std::tr1::decay<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::tr1::_Unrefwrap<_Type>' being compiled
1>          with
1>          [
1>              _Type=bool (__cdecl &)(long,bool)
1>          ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(965): error C2528: 'abstract declarator' : pointer to reference is illegal
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(349): error C2528: 'type' : pointer to reference is illegal
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(967) : see reference to class template instantiation 'std::tr1::add_pointer<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(148): error C2535: 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base(const _Ty1 &,const _Ty2)' : member function already defined or declared
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(134) : see declaration of 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base'
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(174) : see reference to class template instantiation 'std::_Pair_base<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]

Ответы [ 2 ]

2 голосов
/ 18 сентября 2011

Взятие адреса noFunction работает с VC10 и gcc 4.5.2, то есть:

make_pair(a, &noFunction);

В соответствии с опубликованным вами сообщением об ошибке, я думаю, это связано с тем, как VC обрабатывает привязку кrvalues.

1 голос
/ 19 сентября 2011

«Мой вопрос: это дефект в VS2010 или GCC нарушает правила?»

В случае сомнений вините Visual C ++ и / или Билла Гейтса. Обратите внимание, что существует разница между значением noFunction при использовании в вашем коде и типом, определенным BFunction. noFunction будет ссылкой на функцию, тогда как BFunction определяет указатель на функцию. Это немного сложно объяснить, но это может помочь рассмотреть следующую программу.

#include <iostream>
#include <typeinfo>


bool noFunction(long, bool) { return true; }

typedef bool (function_ref)(long, bool);
typedef bool (*function_ptr)(long, bool);

int
main()
{
    std::cout << typeid(noFunction).name() << '\n';
    std::cout << typeid(&noFunction).name() << '\n';
    std::cout << typeid(function_ref).name() << '\n';
    std::cout << typeid(function_ptr).name() << '\n';

    return 0;
}

Кажется, что Visual C ++ задыхается от ссылок на функции. Я не уверен, что существует законная причина, по которой он отвергнет это, но я ожидаю, что вы сможете создать пару с типами, которые являются моделью копирования. Например, вы должны быть в состоянии построить, но не назначать std::pair<int, int const&>.

...