2015-12-06 22 views
8
#include <iostream> 
using namespace std; 

struct CL2 
{ 
    CL2(){} 
    CL2(const CL2&){} 
}; 

CL2 cl2; 

struct CL1 
{ 
    CL1(){} 
    operator CL2&(){cout<<"operator CL2&"; return cl2;} 
    operator const CL2&(){cout<<"operator const CL2&"; return cl2;} 
}; 

CL1 cl1; 

int main() 
{ 
    CL1 cl1; 
    CL2 cl2 (cl1); 
} 

clangとgccの両方があいまいな変換演算子を返しますが、Visual Studioはコンパイルして "演算子const CL2 &"を出力します。スタンダードに沿ってどのように正しくなければなりませんか?
私はundestandとして、CL1のconst CL2への変換&はコピー初期化コンテキスト(cl2オブジェクトの直接初期化の一部として)にあります。私は[over.match.copy]、n4296ドラフトを見:曖昧な変換演算子による参照バインド

「がCV1 Tが」に初期化されるオブジェクトのタイプであると仮定すると、以下のように、Tクラスタイプ 、候補となる機能が選択される:
- Tの変換コンストラクタ(12.3.1)は、候補の 関数です。
- 初期化式のタイプが クラスタイプ "cv S"である場合、Sおよびその 基本クラスの非明示変換関数が考慮されます。バインドされるテンポラリを の初期化時に、パラメータが の「おそらくcv修飾Tを参照する」コンストラクタの最初のパラメータに設定され、コンストラクタが と呼び出されます。 "cv2 T"型のオブジェクトである場合、明示的変換関数も考慮されます。 です。 S内に隠されておらず、 cv非定格バージョンがTと同じ型であるか、またはそれらの派生クラス である型が候補関数である。 「Xへの参照」を返す変換関数は、タイプXの 参照のタイプに応じて、lvaluesまたはxvaluesを返します。したがって、この の候補関数の選択プロセスではXが返されます。

e.e.e.両方の変換演算子は、CL2 - > const CL2 &またはconst CL2 - > const CL2 &のいずれかの変換が優れているので、戻り値CL2とconst CL2(constなしのCL2のみではない)とみなされます。 2番目のケースはより適切と思われます。その文脈でより良い資格の転換が検討されるべきでしょうか?または両方のケースがアイデンティティ変換ですか?標準では見つかりませんでした

+0

奇妙なことに、Visual Studio *はコードをコンパイルします。しかし、* IntelliSense *は第2オブジェクトの宣言に不満を持ちます。私が理解する限り、あなたの問題はあなたが思うものではありません。コンパイラーは、戻り値の型に基づいてオーバーロードできないため、どの変換演算子関数を呼び出すのかわかりませんが、関数の定数に基づいてオーバーロードすることができます。 '演算子const CL2&"を試してください。リターンcl2; } ' – DeiDei

答えて

4

どちらの変換演算子も同じシグネチャを持っているため、[over.match.best] /(1.4)の適用によるものです...

- コンテキストは、ユーザー定義の変換(8.5、 13.3.1.5、および13.3.1.6を参照)および戻りタイプのF1から宛先タイプへの標準変換シーケンス(つまり、 エンティティが初期化されています)は、戻り値タイプF2からへの標準変換シーケンス よりも優れた変換シーケンスです宛先タイプ。

...または(1.5):

- コンテキストは、関数型への参照の結合直接的 参照(13.3.1.6)、[...]

する変換関数によって初期化され

明らかにどちらも当てはまりませんので、あいまいさがあります。曖昧さを解消する方法:

operator CL2&(); 
operator const CL2&() const; 

Demo;ここで、暗黙的オブジェクト引数の前者のオーバーロードの最初の標準変換シーケンスは[over.ics.rank] /(3.2.6)より優れており、over.match.best /(1.3)で決定的です。

+0

ありがとう、私はなぜ彼らが(constを考慮して)同じ署名を持っているのか分かりません?なぜ、[over.match.copy]では "reference to X"と書かれていますが、 "reference to cv X"(Xは "CL2"として推測されますが、 "const CL2"ではなく)と書かれていますか? – user3514538

+0

@ user3514538最初の標準変換シーケンスは2番目の変換シーケンスの前に考慮されます。私。もし 'const'があれば、それは支配的です。 – Columbo

+1

@ user3514538 [over.match.copy]はコピー初期化を扱うため(例では直接初期化を示しています)、適用されません。また、 'X'は任意であり、したがって任意のCV資格を既に含んでいます。 – Columbo