2016-11-11 10 views
2

テンプレートのクラスにoperator<<を実装して、含まれるすべての要素を指定されたstd::ostream&に印刷できるようにしたいと思います。問題は、私が定義した関数を認識させることができないということです。ネストされたプライベートクラスのコレクションを持つクラスのoperator <<を正しくオーバーロードするには?

私が手にエラーが理想的

error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Outer<int>::Inner') 
     os << inner << ", "; 
     ~~~^~~~~~~~ 

私はインライン定義された機能を持っていないたいと思いますが、私もそれがインラインで動作させることはできません。下のコードでは、クラス宣言の外側に定義しようとした私のコメントをコメントアウトしていることがわかります。上記と同じエラーが発生します。

This questionは、オペレータをクラスの友人にすることをお勧めします。私は考えているすべての方法でそれをやってきましたが、それはまだ動作しません。

コード:

#include <iostream> 

template<class T> 
class Outer { 
    class Inner { 
     T item; 
     template<class T_> 
     friend std::ostream& operator<<(std::ostream& os, const typename Outer<T_>::Inner& inner) { 
      os << inner.item; 
      return os; 
     } 
     template<class T_> 
     friend std::ostream& operator<<(std::ostream& os, const Outer<T_> outer); 
    }; 
    std::vector<Inner> inner_items; 
    template<class T_> 
    friend std::ostream& operator<<(std::ostream& os, const Outer<T_> outer); 
    template<class T_> 
    friend std::ostream& operator<<(std::ostream& os, const typename Outer<T_>::Inner& bar); 

}; 

/*template<class T> 
std::ostream& operator<<(std::ostream& os, const typename Outer<T>::Inner& bar) { 
    os << inner.item; 
    return os; 
}*/ 

template<class T> 
std::ostream& operator<<(std::ostream& os, const Outer<T> outer) { 
    for (typename Outer<T>::Inner inner : outer.inner_items) { 
     os << inner << ", "; 
    } 
    return os; 
} 


int main() 
{ 
    Outer<int> outer; 
    std::cout << outer; 
} 

答えて

1

あなただけのタイプを使用し、Innerにtempletizeする(いずれも希望)必要はありません。

あなたは を定義するために失敗した上で書いたもの
class Outer { 
    class Inner { 
     T item; 
     friend std::ostream& operator<<(std::ostream& os, const Inner& inner) { 
      os << inner.item; 
      return os; 
     } 
     // ... 

無料機能Outer<T>::Inneroperator<<(..)です。 2番目のパラメータはOuter<T_>::Innerであり、コンパイラはInnerから定義された型に行くことはできません。

+0

これは機能しますが、クラス宣言の外部の関数を定義することは可能ですか? –

+0

@JonMcClung:http://ideone.com/WVUeWz – lorro

2

はないネストされた種類のテンプレートの出力演算子作りください:

#include <iostream> 
#include <vector> 

template<class T> 
class Outer { 
    class Inner { 
     T item; 
     friend std::ostream& operator<<(std::ostream& os, typename Outer<T>::Inner const& inner) { 
      os << inner.item; 
      return os; 
     } 
     friend std::ostream& operator<<(std::ostream& os, const Outer<T> outer); 
    }; 
    template <typename T_> 
    friend std::ostream& operator<< (std::ostream&, Outer<T_> const&); 
    std::vector<Inner> inner_items; 
}; 

template<class T> 
std::ostream& operator<<(std::ostream& os, Outer<T> const& outer) { 
    for (typename Outer<T>::Inner const& inner : outer.inner_items) { 
     os << inner << ", "; 
    } 
    return os; 
} 

int main() 
{ 
    Outer<int> outer; 
    std::cout << outer; 
} 

をあまりにも、いくつかのconst&を振りかけ、必要なfriend宣言が追加あります。

+0

lorroの答えは、 'Inner'内部の演算子の宣言で' typename Outer :: 'は必要ないことを示しています。なぜそれを含めるのですか?余計なのですか、それとも何か変わるのですか? –

+1

@JonMcClung:まず、資格は元のものです。それを使用しても何も変わることはありませんが、私は一般的に私の名前を完全に修飾するので、私はそれを落とす必要はないと感じました。 –

関連する問題