2012-04-02 15 views
1

私はテンプレートコンストラクタを持つクラスを持っていて、コードは実際にコピーのコンストラクタを呼び出しています。デフォルトのコンストラクタの後では、型が正しくないので意味がありません。例えばC++テンプレートコンストラクタ、なぜコピーコンストラクタが呼び出されていますか?

:作品(適切以外の場合に呼ばれる)が、適切に別のテンプレート関数から「正しい」コンストラクタとして認識されない

class A 
{ 
    public: 
    A(void); // default constructor 
    A(const A& other); // copy constructor 
    template<class TYPE> 
    A(const TYPE& object_to_ref); // template constructor 
}; 

このテンプレートコンストラクタ

template<class TYPE> A& CreateA(const TYPE& object_to_ref) { // THIS FUNCTION IS NEVER SPECIALIZED WITH "A", ONLY WITH "B" !! return *new A(object_to_ref); // CALLS "A::A(const A&)" !!?? } 

例は失敗:

B my_b; 
A& my_a = CreateA(my_b); // "A::A(const A&)" called, not "A::A(const B&)"! 

これは私には意味がありません。コピーコンストラクタに一致する型が間違っています。何が起こった? (MSVC2008)

私の回避策この場合には、テンプレートコンストラクタを使用しないことです。

template<class TYPE> 
A& CreateA(const TYPE& object_to_ref) 
{ 
    A* new_a = new A(); //DEFAULT CONSTRUCTOR 
    new_a->setObjectToRef(object_to_ref); //OTHER TEMPLATE MEMBER FUNCTION 
    return *new_a; 
} 

質問:なぜ、テンプレートコンストラクタは、この場合には呼び出されませんでしたか?

(回避策が適切に動作するように思える、あなたが代替案を提案していますか?)

EDIT:BBおよび/またはAの間で指定されていない変換して、無関係です:

class B 
{ 
}; 
+11

接線注意: 'return * new'を実行するコードは、ほとんど常に悪い考えです... –

+3

ほとんど値が100%に近い値です。 –

+0

'B'が暗黙的に' A'に変換可能な場合、これはコンパイラがテンプレートコードを生成する必要なしに一致するコンストラクタを見つけるために起こります。 – Chad

答えて

1

あなたはBの定義を提供していませんでしたので、ABの祖先であり、Bが暗黙的に0123にキャストされると仮定します。この場合、Bのテンプレートは、完全に適切な呼び出しが既に存在するため、インスタンス化されていません。

+0

申し訳ありませんが、質問を更新しました。いいえ、「B」は無関係です。奇妙な。 – charley

+1

それは意味をなさない。あなたはおそらくあなたの例を単純化しました。 BをAに変換する暗黙の方法がありますか? '演算子A()'と同じですか? – cababunga

+0

あなたはそうだった:理にかなっていない、私は単純すぎた。さらに多くの 'template <> ==> traits ==> template <>'変換が行われていました。そのうち1つは予期せぬものでしたが、最終的にコピーコンストラクタが呼び出されました。私のせい! (グッド!私はCRAZYを運転していました。) – charley

関連する問題