Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a non-standard std::pair implementation, a compiler bug, or a non-standard code?

The following code compiles on VS2005 and 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";
}

But it fails to compile on VS2010 with the error message:

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

I understand that in microsoft's implementation of VS2010 Pr::first is actually a member of _Pair_base. However, AFAIK, it doesn't matter. &Pr::first still must be of a type int Pr::*. Note that the following code compiles fine:

int Pr::* x = &Pr::first;

So, is it a non-standard std::pair implementation, a compiler bug, or a non-standard code?

like image 810
Yakov Galka Avatar asked May 06 '11 07:05

Yakov Galka


2 Answers

The standard provides a clear definition of what a pair is, both in C++03 and C++11 the pair contains two member attributes, and provides exact code of what pair looks like. I would consider that behavior (moving the members to a base class) as a breach of contract as your code is valid according to the standard and it is being rejected by the implementation.

So the implementation of VC2010 is not standard conforming on this particular case.

like image 196
David Rodríguez - dribeas Avatar answered Nov 09 '22 01:11

David Rodríguez - dribeas


The standard doesn't allow any conversion while matching the template parameters (looking for the standard paragraph, will edit in).

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

This instatiates X as (std:: omitted for brevity)

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

But the static type of &Pr::first is

int _Pair_base<int,int>::*

So the compiler would need to do a conversion like displayed in the error. I don't know exactly how gcc implements std::pair, but it seems to do so without inheritance. I'll look it up and edit again.

like image 21
Xeo Avatar answered Nov 09 '22 03:11

Xeo