它是非标准的std :: pair实现,编译器错误还是非标准代码?

时间:2011-05-06 07:42:09

标签: c++ visual-studio-2010

以下代码在VS2005和gcc-4.3.4上编译。

#include <algorithm>
#include <iostream>

template<class C, class T, T C::*x>
struct X { };

typedef std::pair<int,int> Pr;
X<Pr, int, &Pr::first> var;

int main()
{
    std::cout << "hello\n";
}

但它无法在VS2010上编译,并显示错误消息:

1>d:\a\testvs10\testvs10.cpp(13): error C2440: 'specialization' : cannot convert from 'int std::_Pair_base<_Ty1,_Ty2>::* ' to 'int std::pair<_Ty1,_Ty2>::* '
1>          with
1>          [
1>              _Ty1=int,
1>              _Ty2=int
1>          ]
1>          Standard conversion from pointer-to-member of base to pointer-to-member of derived is not applied for template arguments

据我所知,在Microsoft的VS2010 Pr::first实现中,_Pair_base实际上是&Pr::first的成员。但是,AFAIK,没关系。 int Pr::*仍必须属于int Pr::* x = &Pr::first; 类型。请注意,以下代码编译良好:

{{1}}

那么,它是非标准的std :: pair实现,编译器错误还是非标准代码?

3 个答案:

答案 0 :(得分:8)

该标准提供了对一对的清晰定义,在C ++ 03和C ++ 11中,该对包含两个成员属性,并提供了对的外观的精确代码。我认为这种行为(将成员移动到基类)作为违反合同的行为,因为您的代码根据标准有效,并且被实施拒绝。

因此,VC2010的实施并不符合这一特定情况的标准。

答案 1 :(得分:4)

标准在匹配模板参数时不允许任何转换(查找标准段落,将编辑)。

typedef std::pair<int,int> Pr;
X<Pr, int, &Pr::first> var;

这会将X设置为(std::为了简洁而省略)

X<pair<int,int>, int, int pair<int,int>::*>

&Pr::first的静态类型是

int _Pair_base<int,int>::*

因此编译器需要进行错误中显示的转换。我不知道gcc如何实现std::pair,但似乎没有继承。我会查找并再次编辑。

答案 2 :(得分:1)