std::make_pair 的这种用法在 GCC 3 和 4 中工作正常。在 Visual Studio C++ 中则失败。 2010年。为什么?

发布于 2024-12-05 01:49:03 字数 4147 浏览 1 评论 0原文

这在 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 转换为 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>          ]

This compiles fine in GCC 3 and 4. MSVC++ can't figure out the type of noFunction and throws some hideous errors. Note if you cast noFunction to BFunction, it works just fine in VS2010.

My question: is this a defect in VS2010, or GCC bending the rules?

#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

}

N.B. casting noFunction to BFunction fixes the problem in VS2010.

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

.

.

.

Here is the error for reference:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

∞觅青森が 2024-12-12 01:49:03

获取 noFunction 的地址适用于 VC10 和 gcc 4.5.2,即:

make_pair(a, &noFunction);

根据您发布的错误消息,我猜测这与 VC 如何处理与右值的绑定有关。

Taking the address of noFunction works with VC10 and gcc 4.5.2, i.e.:

make_pair(a, &noFunction);

Per the error message you posted, I would guess it has to do with how VC handles binding to rvalues.

鹿! 2024-12-12 01:49:03

“我的问题:这是 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

"My question: is this a defect in VS2010, or GCC bending the rules?"

When in doubt blame Visual C++ and/or Bill Gates. Note that there is a difference between the value of noFunction when used in your code and the type defined by BFunction. noFunction will be a reference to a function whereas BFunction defines a pointer to a function. It is a bit hard to explain but it might help to contemplate the following program.

#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;
}

It seems that Visual C++ is choking on function references. I'm not sure if there is a legitimate reason why it would reject that but I would expect that you should be able to construct a pair with types that are a model of copy constructable. Eg you should be able construct but not assign std::pair<int, int const&>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文