Это нестандартная реализация std :: pair, ошибка компилятора или нестандартный код? - PullRequest
8 голосов
/ 06 мая 2011

Следующий код компилируется на 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. Однако, AFAIK, это не имеет значения. &Pr::first все еще должен иметь тип int Pr::*. Обратите внимание, что следующий код компилируется нормально:

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

Итак, это нестандартная реализация std :: pair, ошибка компилятора или нестандартный код?

Ответы [ 3 ]

8 голосов
/ 06 мая 2011

Стандарт обеспечивает четкое определение того, что такое пара, как в C ++ 03, так и в C ++ 11 пара содержит два атрибута-члена и предоставляет точный код того, как выглядит пара. Я бы посчитал это поведение (перемещение членов в базовый класс) нарушением контракта, поскольку ваш код действителен в соответствии со стандартом и отклоняется реализацией.

Таким образом, реализация VC2010 не соответствует стандарту в данном конкретном случае.

4 голосов
/ 06 мая 2011

Стандарт не допускает никакого преобразования при сопоставлении параметров шаблона (ищет стандартный абзац, будет редактировать в нем).

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, но, похоже, он делает это без наследования.Я посмотрю и отредактирую снова.

1 голос
/ 08 мая 2011

Да, это ошибка. Нашел отчет об ошибке здесь:

http://connect.microsoft.com/VisualStudio/feedback/details/558993/std-pair-members-are-not-members-of-std-pair

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