2012-02-17 16 views
2

私は私のヘッダファイルに次のようにしている。C++テンプレート演算子のオーバーロードで自動コンストラクタコール?

template<typename T> 
class rational { 
private: 
    T num; 
    T denom; 
    T gcd(T x, T y); 

public: 
    rational(T num, T denom); 
    rational(T wholeNumber); 

    template<typename U> 
    friend inline rational<U> operator *(const rational<U> &lhs, const rational<U> &rhs); 
} 

template<typename T> 
rational<T>::rational(T whole) { 
    this->num = whole; 
    this->denom = 1; 
} 

template<typename T> 
rational<T> operator *(const rational<T> &lhs, const rational<T> &rhs) { 
    return rational<T>(lhs.num * rhs.num, lhs.denom * rhs.denom); 
} 

そして、私のメインの中で次のよう

rational<int> x(6), y(2); 
rational<int> product = y * x; // this works 
rational<int> product2 = 2 * x; // this doesn't 

最初の製品は動作しますが、二番目は私に「エラー与える: 'の不一致を演算子* 'in' 2 * x '"となります。どうして?引数として2だけを取るコンストラクタがあるので、自動的に呼び出されるべきではありませんか?もしそうでなければ、私はこれらの両方の作業をするためにオペレータをどのように過負荷にするでしょうか?

ありがとうございました。

+2

変換が動作しない理由、だけでなく、修正、[この回答](http://stackoverflow.com/a/で説明されています。

正しい方法は持っていることです3888237/160206)。 –

+0

[暗黙の変換が起こっていない]の重複が考えられます(http://stackoverflow.com/questions/3888082/implicit-conversion-not-happening) – wilx

答えて

0

コンパイラが合理的に生産するために、2に暗黙的に単一引数のコンストラクタを呼び出すことはありませんなぜ私はわからないんだけど、私の推測では、テンプレートが含まれる場合、推論機構は単に壊れているということです。

つの回避策(誰が暗黙のコンストラクタの問題を修正する方法を知っていない場合)ので、のような追加の乗算演算子を定義することです:

template<typename T> 
rational<T> operator *(const T &lhs, const rational<T> &rhs) { 
    return rational<T>(lhs * rhs.num, rhs.denom); 
} 
template<typename T> 
rational<T> operator *(const rational<T> &lhs, const T &rhs) { 
    return rational<T>(lhs.num * rhs, lhs.denom); 
} 

あなたは、高性能のコードを書いている場合、これはまた、パフォーマンスが向上しますどこかの内側のループで有理数を使う。

+0

ありがとうございます。私もこれを念頭に置いてフォールバックとして考えましたが、これを避けてコンストラクタに依存する方法が本当にあることを願っています。さもなければ、私は不必要に冗長であると感じるすべてのバイナリ演算子に対してこれを行う必要があります。 –

+0

@Foober StackoverflowはQAサイトです。そのようなものとして、意見は意見の上に奨励されます。 「私の推測」と「単純に壊れている」というのは本当に建設的なものではない。 C++は明確に定義された言語であり、どのように動作するかを説明するだけでよいでしょう。 – sehe

+0

問題の一部は、「これらの両方の作業を行うためにオペレータに過負荷をかける方法は他にありませんか」でした。私はそれに働く答えを提供したと信じています。気にして申し訳ありません。 – Fooberman

-1
2 * x; 

int::operator*(const rantional<int>&) 

2、の呼び出しに類推相当intであり、それはoperator *const rational<int>&のためにオーバーロードされていないです。したがって、コンパイラエラーが発生します。

rational<int> product2 = rational<int>(2) * x; // ok 
+0

私はそれを理解していますが、コンパイラは合理的なコンストラクタ(int)を引数から推論できるはずだと考えました。私の質問は、その推論がなぜ起こっていないのかについてです。 –

+0

@DavidThielke、私はすでに私の答えの理由を説明しました。このような暗黙的な変換は起こりません。 – iammilind

関連する問題