2016-07-05 18 views
2

私はクラステンプレートのため'+'演算子をオーバーロードしようとしているが、中置記法を使用して、それを呼び出す未解決の外部シンボルエラーを取得しています:未解決の外部シンボルエラー演算子オーバーロード+テンプレート

// In main.cpp 

template<class T> 
struct B 
{ 
    B(T t) : t_(t) {} 
    friend B operator+(B const &lhs, B const &rhs); 
    T t_; 
}; 

template<class T> 
B<T> operator+(B<T> const &lhs, B<T> const &rhs) 
{ 
    return B<T>(lhs.t_ + rhs.t_); 
} 

int main() 
{ 
    B<int> b = 1; 
    b = operator+<int>(b, 2); // works but clunky syntax 
    // b = b + 2; // LNK2019: unresolved external symbol 
} 

これは、通常の非テンプレートのために正常に動作しますクラスでは同じことをここで達成できるかどうか疑問に思っています。

私は、Visual C++ 2015

+1

'友人B演算子+(Bのconstの&LHS、Bのconstの'されていないテンプレート宣言は、しかし、あなたは1を定義し – LogicStuff

+0

ものhttp参照してください。: //stackoverflow.com/questions/11864102/why-is-friend-member-function-not-recognized-as-function-template-automatically –

+0

現在、すべてのメンバーは 'public'なので、' friend'は必要ありません。 - ) – Jarod42

答えて

3
friend B operator+(B const &lhs, B const &rhs); 

を使用していますが、非テンプレート関数です。

単純にはinlineそれを定義するには、次のようになります。

あなたはすべてのテンプレート友人に

template <typename T> struct B; 

template <typename T> B<T> operator+(B<T> const &lhs, B<T> const &rhs); 

template<class T> 
struct B 
{ 
    B(T t) : t_(t) {} 

    template <typename U> 
    friend B<U> operator+(B<U> const &lhs, B<U> const &rhs); 
    T t_; 
}; 

Demo

か、単に特定のものを宣言する必要がありそうで

template<class T> 
struct B 
{ 
    B(T t) : t_(t) {} 
    friend B operator+(B const &lhs, B const &rhs) 
    { 
     return B(lhs.t_ + rhs.t_); 
    } 
    T t_; 
}; 

Demo

template <typename T> struct B; 

template <typename T> B<T> operator+(B<T> const &lhs, B<T> const &rhs); 

template<class T> 
struct B 
{ 
    B(T t) : t_(t) {} 
    friend B operator+<>(B const &lhs, B const &rhs); 
    // Note the <> 

    T t_; 
}; 

template<class T> 
B<T> operator+(B<T> const &lhs, B<T> const &rhs) 
{ 
    return B<T>(lhs.t_ + rhs.t_); 
} 

Demo

+0

それをインラインで定義することはできますが、私の実際のクラスにはもっと多くのものが内部にあるので、避けたいのです。私はテンプレート関数を定義できませんでしたが、あなたのソリューションを試しましたが、どちらの場合も 'C2678:binary '+':演算子が見つかりませんでした。 'B 'の左辺オペランドを取る受け入れ可能な変換) '。 –

+0

@GeorgeSkelton:リンクを追加しました。 – Jarod42

+0

ああ私はあなたが感謝の意味を参照してください。しかし 'int 'から' B 'を推論することができないので、まだ 'b + 1'をコンパイルしません。しかし、メンバー関数はそのような控除を行うことができます。これは友人の機能に内在する制限ですか? –

0

あなたは、クラス内のテンプレートとしてそれを定義していません。 最も簡単な解決策は、クラス内の関数を定義している(インライン):

template<class T> 
struct B 
{ 
    B (T t) : t_ (t) {} 
    friend B operator+ (const B &lhs, const B &rhs) 
    { 
     return B (lhs.t_ + rhs.t_); 
    } 
    T t_; 
}; 
関連する問題