2012-04-20 3 views
1

Следующий код компилируется на gcc 4.6, но не 4.7. Это проблема 4.7 или проблема 4.6? Скомпилирован с -std = gnu ++ 0x.gcc 4.7 Недостаток библиотеки STL на реализацию пары?

#include <utility> 

using namespace std; 

struct Z { 
}; 

struct X { 
    operator Z*() const { return nullptr; } 
}; 

struct Y { 
    Y(Z*) {} 
}; 

int main() { 
    pair<int, Y> p(make_pair(0, X())); 
} 

Сообщения об ошибках:

[hidden]$ g++-mp-4.6 -std=gnu++0x e.cpp 
[hidden]$ g++-mp-4.7 -std=gnu++0x e.cpp 
e.cpp: In function 'int main()': 
e.cpp:17:37: error: no matching function for call to 'std::pair<int, Y>::pair(std::pair<int, X>)' 
e.cpp:17:37: note: candidates are: 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:204:9: note: template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> std::pair::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:204:9: note: template argument deduction/substitution failed: 
e.cpp:17:37: note: 'std::pair<int, X>' is not derived from 'std::tuple<_Args1 ...>' 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:153:9: note: template<class ... _Args1, class ... _Args2> std::pair::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:153:9: note: template argument deduction/substitution failed: 
e.cpp:17:37: note: cannot convert 'std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = X; typename std::__decay_and_strip<_T2>::__type = X; typename std::__decay_and_strip<_T1>::__type = int]((* & X()))' (type 'std::pair<int, X>') to type 'std::piecewise_construct_t' 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:148:12: note: template<class _U1, class _U2, class> constexpr std::pair::pair(std::pair<_U1, _U2>&&) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:148:12: note: template argument deduction/substitution failed: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:145:38: error: no type named 'type' in 'struct std::enable_if<false, void>' 
/opt/local/include/gcc47/c++/bits/stl_pair.h:142:12: note: template<class _U1, class _U2, class> constexpr std::pair::pair(_U1&&, _U2&&) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:142:12: note: template argument deduction/substitution failed: 
e.cpp:17:37: note: candidate expects 2 arguments, 1 provided 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:136:12: note: template<class _U2, class> constexpr std::pair::pair(const _T1&, _U2&&) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:136:12: note: template argument deduction/substitution failed: 
e.cpp:17:37: note: cannot convert 'std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = X; typename std::__decay_and_strip<_T2>::__type = X; typename std::__decay_and_strip<_T1>::__type = int]((* & X()))' (type 'std::pair<int, X>') to type 'const int&' 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:131:12: note: template<class _U1, class> constexpr std::pair::pair(_U1&&, const _T2&) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:131:12: note: template argument deduction/substitution failed: 
e.cpp:17:37: note: candidate expects 2 arguments, 1 provided 
In file included from /opt/local/include/gcc47/c++/utility:72:0, 
       from e.cpp:1: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:122:7: note: std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int; _T2 = Y; std::pair<_T1, _T2> = std::pair<int, Y>] 
/opt/local/include/gcc47/c++/bits/stl_pair.h:122:7: note: no known conversion for argument 1 from 'std::pair<int, X>' to 'std::pair<int, Y>&&' 
/opt/local/include/gcc47/c++/bits/stl_pair.h:119:17: note: constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = int; _T2 = Y; std::pair<_T1, _T2> = std::pair<int, Y>] 
/opt/local/include/gcc47/c++/bits/stl_pair.h:119:17: note: no known conversion for argument 1 from 'std::pair<int, X>' to 'const std::pair<int, Y>&' 
/opt/local/include/gcc47/c++/bits/stl_pair.h:116:12: note: template<class _U1, class _U2, class> constexpr std::pair::pair(const std::pair<_U1, _U2>&) 
/opt/local/include/gcc47/c++/bits/stl_pair.h:116:12: note: template argument deduction/substitution failed: 
/opt/local/include/gcc47/c++/bits/stl_pair.h:113:38: error: no type named 'type' in 'struct std::enable_if<false, void>' 
/opt/local/include/gcc47/c++/bits/stl_pair.h:104:26: note: constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = int; _T2 = Y] 
/opt/local/include/gcc47/c++/bits/stl_pair.h:104:26: note: candidate expects 2 arguments, 1 provided 
/opt/local/include/gcc47/c++/bits/stl_pair.h:100:26: note: constexpr std::pair<_T1, _T2>::pair() [with _T1 = int; _T2 = Y] 
/opt/local/include/gcc47/c++/bits/stl_pair.h:100:26: note: candidate expects 0 arguments, 1 provided 
+3

Нет сообщения об ошибке, нет ответа. Пожалуйста, сообщите, в чем проблема, предоставив сообщение об ошибке. – Klaim

+3

@icando: Воспроизведение этого может потребовать установки двух компиляторов перед компиляцией короткой программы. Я думаю, что вполне разумно не беспокоиться об этом. –

+0

Жаль, что я не хотел быть грубым, но «нет сообщения об ошибке, никакого ответа» звучит грубо для меня в первую очередь. Это просто звучит так, будто я не занимался исследованиями, и проблема глупа. –

ответ

5

Это не должно составить.

Инициализация p.second требует неявного преобразования от X до Y. Неявное преобразование может включать в себя не более одного пользовательского преобразования. Требуемое преобразование потребует двух; X - Z* через оператор преобразования и Z* - Y через конструктор преобразования.

Инициализация элементов пары из другой пары допускается только посредством неявных преобразований. C++ 11 говорит:

20.3.2/12 Этот конструктор не должен участвовать в разрешении перегрузки, если const U& не неявно конвертируются в first_type и const V& является неявно конвертируемым в second_type.

и C++, 98 сказал:

20.2.2/4 инициализирует членов от соответствующих членов аргумента, выполняя неявные преобразования по мере необходимости.

Предположительно, у более старой версии была ошибка, позволяющая учитывать это преобразование, и эта ошибка была исправлена ​​в более поздней версии.

+0

Это не правда, на самом деле. Под gcc4.7, заменив строку на '' Y y (X()), '' будет компилироваться. Таким образом, gcc4.7 знает преобразование из X в Y. –

+0

@icando: точка не в знании некоторой последовательности преобразований, точка зрения о том, какие последовательности преобразований разрешены для рассмотрения при разрешении перегрузки. У компилятора, безусловно, достаточно информации, чтобы найти последовательность конверсий, включающую дюжину конверсий, но их просто не разрешается рассматривать. – PlasmaHH

+0

@icando: 'Y y (X());' - досадный синтаксический анализ; он объявляет функцию, которая принимает указатель на функцию в качестве аргумента. 'Y y = X();' пытается инициализировать 'Y' from и' X', и вы должны обнаружить, что это не компилируется. –

Смежные вопросы