以下のコードを検討してください。
#include <cstdio>
struct A
{
A(){}
explicit A(const A&) {std::puts("copy");}
};
int main()
{
A a;
true ? a : A();
return 0;
}
私は、三元、コピーしようと理解したようやコピーコンストラクタは、明示的であるため、失敗する必要があり、しかし、gccがこれだけで罰金をコンパイルし、コピーを作成します。Clangは期待どおりにエラーを吐き出します。
これはgccのバグですか?
c ++ 17モードでgcc8.1とclang7.0を使用していますが、c ++ 98モードのコンパイラエクスプローラーですべてのバージョンのgccを試しましたが、すべて同じように動作します。
Clangはそれを拒否する権利があり、それは確かにGCCのバグです。簡単にするために、n4659(C ++ 17標準に最も近いドキュメント)を引用します。
何よりもまず、[expr.cond]¶6で指定されている例の条件式の型は、型のprvalueでなければなりませんA
。
さて、[expr.cond]¶7によると、私の強調:
左辺値から右辺値、配列からポインター、および関数からポインターの標準変換は、2番目と3番目のオペランドで実行されます。
a
左辺値から右辺値への変換を実行できる必要があります。[conv.lval]¶3.2(ここでも強調鉱山)で次のようにa
指定されているのはどれですか
それ以外の場合、Tにクラスタイプがある場合、変換はglvalueから結果オブジェクトをコピー初期化します。
コピーの初期化A
からはA
、どのようなコンテキストで、オーバーロード解決(に変換コンストラクタを選ぶべきである[over.match.copy]¶1.1):
Tの変換コンストラクターは候補関数です。
また、明示的なコピーコンストラクターは変換コンストラクターではありません([class.conv.ctor]¶3)
非明示的なコピー/移動コンストラクタ([class.copy])は変換コンストラクタです。
準拠するC ++実装は、作成した条件式を整形式として受け入れることができません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加