2012-04-09 33 views
2

すべてのユーザー定義型にオペレータ< <とsc_trace()関数が必要なSystemCライブラリを使用しています。しかし、ユーザー定義型は実際には、テンプレートクラス内でネストされた型です。なぜなら、「ネスト型」は外部クラスで指定されたテンプレート引数から計算されるからです。入れ子型のテンプレート関数を推定できません

template<typename T> 
class Block { 
    typedef typename transform<T>::value NewType; 
public: 
    struct SomeType { 
     SomeType() {} 
     SomeType(T val) : member(val) {} 
     NewType member; 
    }; 
}; 

私は、コンパイラは、ストリーミング演算子を使用してネストされた定義された型をダンプしようとする試みを行うのSystemCライブラリ内の呼び出しを推測することはできませんので

template<typename T> 
std::ostream& operator<<(std::ostream& os, const typename Block<T>::SomeType& type) { 
    return os << type.member; 
} 

ようSomeTypeためのオペレータ< <を定義します。私はライブラリコードに触れていないので(私のコントロール外)。あなたの専門家のうちの誰かがこれを回避する方法を知っていますか?

クリーンな回避策がない場合は、C++ 11にこの解決策があるかどうかを知りたいですか?

+0

'typenameブロック :: SomeType const&type'を試してみてください。 – ildjarn

+0

オペレータをどこで定義しましたか?ヘッダー '.h'ファイルまたはソース' .cpp'ファイルの中に定義しましたか? (C++ 11は[extern template](http://stackoverflow.com/questions/6870885/how-to-use-extern-template)のコンセプトをサポートしていますが、これはテンプレートと関係があります) –

+1

解決策が見つかった場合は、それを回答に追加し、合格とマークしてください。 –

答えて

1

実際に自分で解決策を見つけました。 Vandevoorde/JosuttisのBarton-Nackman Trickと呼ばれています。

重要なのは、機能テンプレートの使用を避けることです。標準では、依存するテンプレートクラスのネストされた型はテンプレート引数の控除から除外されます。オペレータ< <とsc_trace関数は、テンプレートクラスのフレンド関数として定義する必要があります。このようにして、テンプレートクラスがインスタンス化されたときに関数はテンプレート化されていない関数ですが、friendキーワードを使用すると、関数は囲み名前空間のスコープをとります。

関連する問題