2017-08-04 5 views
2

オーバーロード演算子+を混在型で使用したい。 非テンプレートクラスに問題はありません。 テンプレートクラスで動作させるには、フレンド operator + inside classを追加しました。テンプレートと組み込みコンストラクタのクラス定義の外にあるフレンド宣言

template <typename T> class Wrapper 
{ 
    T _val; 
public: 
    Wrapper(T val) :_val(val){} 
    T getValue() const { return _val; } 

    friend Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2) 
    { 
     return Wrapper<T>(val1.getValue() + val2.getValue()); 
    } 
}; 

int main() 
{ 
    Wrapper<int> v1 = 10; // OK, implicit constructor 
    Wrapper<int> v2(20); 
    Wrapper<int> result1 = v1 + v2; // OK, both values are of type Wrapper<int> 
    Wrapper<int> result2 = v1 + 40; // Ok, casting by implicit constructor works 
    return 0; 
} 

は今、私はこのようなクラスの外にオペレータ+実装を移動したい:

#include <iostream> 
#include <string> 

template <typename T> class Wrapper; 

template <typename T> Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2); 

template <typename T> class Wrapper 
{ 
    T _val; 
public: 
    Wrapper(T val) :_val(val){} 
    T getValue() const { return _val; } 

    friend Wrapper<T> operator+ <>(const Wrapper<T>& val1, const Wrapper<T>& val2); 
}; 

// template<class T> Wrapper<T> operator+(const Wrapper<T>&, const Wrapper<T>&) 
// template argument deduction/substitution failed 
template <typename T> Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2) 
{ 
    return Wrapper<T>(val1.getValue() + val2.getValue()); 
} 

int main() 
{ 
    Wrapper<int> v1 = 10; // OK, implicit constructor 
    Wrapper<int> v2(20); 
    Wrapper<int> result1 = v1 + v2; // OK, both values are of type Wrapper<int> 

    // note: mismatched types 'const Wrapper<T>' and 'int' 
    Wrapper<int> result2 = v1 + 40; // Error 
    return 0; 

} 

が、それは私がエラー(上記のコードにそれらを貼り付け)をコンパイル与えます。 修正できますか? (動作しない)(作業)

http://cpp.sh/5j5zg http://cpp.sh/9saow

+0

男、感謝 – amplifier

+0

【関連質問](https://stackoverflow.com/questions/9787593)、うん@justin。その短いことは、考えられるすべてのテンプレートインスタンス化をコンパイラがテストして、あなたが探している暗黙の変換をサポートしているかどうかを調べることではないということです。 –

+0

関連:https://stackoverflow.com/a/4661372/1896169 – Justin

答えて

1

それはテンプレート関数ではありません。この種のフレンド関数を作るために少し奇妙です。あなたはそれがfriend operator+テンプレート機能することによって、しかし、仕事を得るために少しのまわりでそれを変更することができます。

template <typename T> 
class Wrapper 
{ 
    T _val; 
public: 
    Wrapper(T val) :_val(val){} 
    T getValue() const { return _val; } 

    template <typename U> 
    friend Wrapper<U> operator+(const Wrapper<U>& val1, const Wrapper<U>& val2); 
}; 

template <typename T> 
Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2) 
{ 
    return Wrapper<T>(val1.getValue() + val2.getValue()); 
} 

これはほとんどあなたが意図したとおりに動作しますが、これはテンプレート関数であるため、暗黙的な変換が無効になっています。これは、しかし、後ろにそれらを追加することは簡単です:

template <typename T> 
Wrapper<T> operator+(const Wrapper<T>& val1, const T& val2) 
{ 
    return Wrapper<T>{ val1.getValue() + val2 }; 
} 

template <typename T> 
Wrapper<T> operator+(const T& val1, const Wrapper<T>& val2) 
{ 
    return Wrapper<T>{ val1 + val2.getValue() }; 
} 

Live on Coliru

関連する問題