#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番目のケースはより適切と思われます。その文脈でより良い資格の転換が検討されるべきでしょうか?または両方のケースがアイデンティティ変換ですか?標準では見つかりませんでした
奇妙なことに、Visual Studio *はコードをコンパイルします。しかし、* IntelliSense *は第2オブジェクトの宣言に不満を持ちます。私が理解する限り、あなたの問題はあなたが思うものではありません。コンパイラーは、戻り値の型に基づいてオーバーロードできないため、どの変換演算子関数を呼び出すのかわかりませんが、関数の定数に基づいてオーバーロードすることができます。 '演算子const CL2&"を試してください。リターンcl2; } ' – DeiDei