Iは クローンメンバ関数を使用して(存在する場合)、コピーにバック コンストラクタを落下してオブジェクトを複製しようとした以下のC++ 0Xコードで:不正な形式のC++ 0xコードまたはコンパイラのバグ?
struct use_copy_ctor {};
struct prefer_clone_func : use_copy_ctor {};
template<class T>
auto clone(T const* ptr, prefer_clone_func)
-> decltype(ptr->clone())
{ return ptr->clone(); }
template<class T>
auto clone(T const* ptr, use_copy_ctor)
-> decltype(new T(*ptr))
{ return new T(*ptr); }
struct abc {
virtual ~abc() {}
virtual abc* clone() const =0;
};
struct derived : abc
{
derived* clone() const { return new derived(*this); }
};
int main()
{
derived d;
abc* p = &d;
abc* q = clone(p,prefer_clone_func());
delete q;
}
考え自動を使用することですテンプレート型引数の減算(SFINAE)と の一部として、間違った形式の 式を除外するには、 - > decltype(expr)を使用して、両方のクローン関数テンプレートのあいまいさを解決してください。 部分的順序付けwrt第2の関数パラメータ。
残念ながら、GCC 4.5.1は、このプログラムは受け付けていません:
test.cpp: In function 'int main()':
test.cpp:28:39: error: cannot allocate an object of abstract type
'abc'
test.cpp:14:12: note: because the following virtual functions are
pure within 'abc':
test.cpp:16:16: note: virtual abc* abc::clone() const
test.cpp:28:39: error: cannot allocate an object of abstract type
'abc'
test.cpp:14:12: note: since type 'abc' has pure virtual functions
さて、質問です、これはコンパイラのバグですか、私はSFINAEがここで適用される を負い間違っていましたか?私はしっかりとした推論で答えを感謝します。
編集:私は、コードが原因で、この場合の第1関数テンプレートを好むオーバーロードの解決のコンパイルdecltype(new T(*ptr))
T*
に変更した場合 。しかしこれは、関数宣言の一部として表現を持つという目的を破るものです。目的は、コンパイラがエラーの場合に設定されたオーバーロード解像度から関数をキックさせることです。
継承が関係しているので、私は「選択」引数を参照することにします。あなたの問題を解決するものではありません... –
@Matthieu:このタグを発送する作業を参照する必要はありません。部分オーダリングオーバーロード解決規則は依然として適用されます。私はこれがコンパイラによってどのように最適化されているかチェックしていませんが、libstdC++は参照なしでタグのディスパッチを使ってstd :: advanceを実装しています。 – sellibitze
私はそれが必須ではないことを知っています、私はまだオブジェクトのスライスを避けるために、(私はタグがデータ/メソッドを持っているとは限りません...) –