コピーコンストラクタとテンプレート
昨日の1件を追っていったところ、どうも下記の問題に集約されるようです。
class hoge { public: // (09/10: コロン忘れを訂正) hoge(){} template<class T> hoge(T x, int dummy=0) { } }; int main() { hoge h1; hoge h2(h1, 0); }
結果は、
コンパイラ | 結果 |
---|---|
Visual C++ 8.0 | hoge(hoge, int)が見つからない |
CodeWarrior 8.3 | コンパイラ内部エラー |
g++ 3.4.2 | OK |
とまちまちです。
規格を見ると、
12.8 Copying class objects 3 A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cvqualified) X and either there are no other parameters or else all other parameters have default arguments. A member function template is never instantiated to perform the copy of a class object to an object of its class type. [Example:struct S { template<typename T> S(T); }; S f(); void g() { S a( f() ); // does not instantiate member template }-end example]
となっています。(リンク先はCryoliteさんのマネ、いつの間にか$30になっている)
ill-formedという表現が微妙ですが、続きの文を読む限り、「コピーコンストラクタとしてはill-formed」という意味だと思います。(CodeWarriorの動作が不正なのは言うまでもありません)
上の例のh2はコピーコンストラクタの呼び出しではないので、g++の動きが正しいと思います。
やっぱりVC8の動きが正しそうです。(コメント欄参照)
さて、Hamigaki.Coroutineの場合ですが、g++の場合だけ正しい動作をするがゆえにコンパイラ間の動きが違うため、少々混乱していたようです。
落ち着いて基底クラスから順に必要なコンストラクタを定義していった結果、SFINAEなし(CodeWarrior 8.3はSFINAEが動かない)で無事実装することができました。
<hamigaki/coroutine/detail/coroutine_template.hpp>