2012-04-20 10 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

@cando:これを再現するには、ショートプログラムをコンパイルする前に2つのコンパイラをインストールする必要があります。私はそれをするのが気にならないのはかなり合理的だと思います。 –

+0

申し訳ありませんが、私は失礼ではありませんでしたが、最初に「エラーメッセージも無回答」も無礼です。私は何の研究もしなかったように聞こえますが、問題はばかげています。 –

答えて

5

コンパイルべきではありません。

p.secondの初期化では、XからYへの暗黙的な変換が必要です。暗黙の変換には、最大で1つのユーザー定義変換のみが必要です。必要な変換には2つ必要です。 XZ*を変換演算子で、Z*Yをコンバージョンコンストラクタを介して返します。

他のペアからのペア要素の初期化は、暗黙の変換によってのみ許可されます。 C++ 11は言う:const U&first_typeに暗黙的に変換され、const V&second_typeから暗黙的に変換でない限り

20.3.2/12このコンストラクタはオーバーロードの解決に参加してはなりません。

とC++ 98は言った:

20.2.2/4引数の対応するメンバーから初期化部材、必要に応じて、暗黙的な変換をを行います。

おそらく古いバージョンにはこの変換を考慮したバグがあり、そのバグはより新しいバージョンで修正されていると思われます。

+0

実際はそうではありません。 gcc4.7では、行を '' Y y(X()); ''に置き換えるとコンパイルされます。したがって、gcc4.7はXからYへの変換を知っています。 –

+0

@cando:変換シーケンスを知ることは重要ではなく、過負荷解決の際にどのような変換シーケンスを考慮できるかがポイントです。コンパイラには、十数回の変換を含む変換シーケンスを見つけるのに十分な情報がありますが、考慮する必要はありません。 – PlasmaHH

+0

@icando: 'Y y(X());'は厄介な構文解析です。それは引数として関数ポインタを取る関数を宣言します。 'Y y = X();'は 'Y'と' X'を初期化しようとします。コンパイルされていないことがわかります。 –

関連する問題