2010-12-04 7 views
4

ここには、いくつかの関連するクラスがあります。 1つはフロートのリストを含んでいます。 1つはただ1つを含んでいる。時には私は、これらを一緒に掛けたいと言います。その場合、リスト以外のものをリストに「プロモート」したいと思います。ここにコードがあります。これは私が望むのと同じように動作します。私がテンプレート化したときに暗黙の変換が起こっていない

#define LIST_SZ 4 

class Vec1; 

class Vec1_list { 

    public: 
     Vec1_list() {} 
     Vec1_list(const Vec1& in); 

     float x[LIST_SZ]; 
}; 

class Vec1 { 

    public: 
     Vec1() {} 
     Vec1(const float& in); 

     float x; 
}; 

Vec1::Vec1(const float& in) { 
    x = in; 
} 

Vec1_list::Vec1_list(const Vec1& in) { 
    for (int i = 0; i < LIST_SZ; i++) { 
     x[i] = in.x; 
    } 
} 

Vec1_list operator*(const Vec1_list& a, const Vec1_list& b) { 
    Vec1_list tmp; 

    for (int i = 0; i < LIST_SZ; i++) { 
     tmp.x[i] = a.x[i]*b.x[i]; 
    } 

    return tmp; 
} 

int main(void) { 
    Vec1 v1; 
    Vec1_list v2, v3, answer; 

    answer = v1*v3; 
} 

しかし、今、私はそうのようにそれをテンプレート化したいと言う....

#define LIST_SZ 4 

template <typename T> class Vec1; 

template <typename T> 
class Vec1_list { 

    public: 
     Vec1_list() {} 
     Vec1_list(const Vec1<T>& in); 

     T x[LIST_SZ]; 
}; 

template <typename T> 
class Vec1 { 

    public: 
     Vec1() {} 
     Vec1(const T& in); 

     T x; 
}; 

template <typename T> 
Vec1<T>::Vec1(const T& in) { 
    x = in; 
} 

template <typename T> 
Vec1_list<T>::Vec1_list(const Vec1<T>& in) { 
    for (int i = 0; i < LIST_SZ; i++) { 
     x[i] = in.x; 
    } 
} 

template <typename T> 
Vec1_list<T> operator*(const Vec1_list<T>& a, const Vec1_list<T>& b) { 
    Vec1_list<T> tmp; 

    for (int i = 0; i < LIST_SZ; i++) { 
     tmp.x[i] = a.x[i]*b.x[i]; 
    } 

    return tmp; 
} 

int main(void) { 
    Vec1<float> v1; 
    Vec1_list<float> v2, v3, answer; 

    answer = v1*v3; 
} 

「MULT」は、この時間をチョークするようにコンパイラーに指示します - それは自動的に私のVEC1を起動しません - > Vec1_listコンストラクタ。これはC++での人生の事実ですか、あるいはこれを自動的に行うために私が使用できる方法はありますか?代わりに、私は機能から巨大なファンを持つ必要があるということです。

答えて

1

Vec1_listがインスタンス化されて変換が実行されたときにインスタンス化されるように、Vec1_listクラスのフレンドとしてoperator*を宣言する必要があります。

EDIT: 、そうVec1_listクラステンプレート宣言に演算子*の定義を移動するには:

friend static Vec1_list operator*(const Vec1_list& a, const Vec1_list& b){ 
    /* ... */ 
} 
0

私はなぜそれが望みに昇進しないのかわかりませんVec1_list。しかし、それが不可能な場合は、いつでもこれを行うことができます:

template <typename T> 
Vec1_list<T> operator*(const Vec1<T>& a, const Vec1_list<T>& b) { 

    return Vec1_list<T>(a)*b;; 
} 

ところで、私はまだ元の問題を掘っています。

1

変換コンストラクタによるユーザー定義の変換は、テンプレート引数の控除では考慮されません。

テンプレート控除では、パラメータ型をと同じにする関数テンプレートパラメータの置換を引数の型に置き換えようとします。それができないときは、const/volatile修飾修飾か 'ポインタからの変換に派生したもの'にすることができます(ここでは単純化しています)。

これは、標準[temp.deduct.call]のセクション14.8.2.1/3に記載されています。

関連する問題