2016-09-10 6 views
1

私はいくつかのノートを書いています。ちょうどコンパイルのために、私はとしてostreamのためにoperator<<オーバーロードされた関数を追加しました。これはうまくコンパイルされますが、class typeのオペレータに<>templateがオーバーロードされ、そのタイプがオーバーロードされた関数の2番目の入力として渡されたので、今から定義するすべてのクラスに対してnew演算子を使用しませんか? 参考のために私のコードです。 純粋にメモの目的であり、機能はありません。演算子をテンプレートとしてオーバーロードするとどうなりますか?

template <class type> 
ostream& operator<< (ostream& s, type x){ 
    s << x.getsmth(); 
    //... 
} 
+0

*「それは私が今から定義EVERYクラスのnew演算子を使用しないのだろうか? "*はい、本質的に。だからこそテンプレート化されたオーバーロードを追加するのは賢明ではありません。 –

+0

もちろん、そこで呼び出されたメソッドが見つからないと、コンパイラは狂気のように文句を言うでしょう。私もそう思っていました。 –

+0

EVERYクラスではなく、(クラスに固有の)より一層良いオーバーロードを持たず、定義したテンプレートと同じ名前空間にある(ADL(http:// en) .cppreference.com/w/cpp/language/adl)のルール)。 –

答えて

0

それはSFINAEに来るとき、私は初心者の自分だけど、あなたが正しいことのように、このテンプレートは、体がコンパイルされませんが、getsmth()を提供していないクラス用に使用されるようです。あなたは、これは期待通りに動作しているようです、しかしSFINAEでこれを防ぐことができます。

template <class T, typename = decltype(T().getSomething())> 
std::ostream& operator<< (std::ostream& s, T& x){ 
    s << x.getSomething(); 
    return s; 
} 

デモ:http://cpp.sh/8fyk

+0

ええ、あなたは実際にそれを行うことができますが、何がポイントですか?あなたがクラスの中でそれを定義すれば、それはあなたに問題を保存します。 私は別のことをすることができると思います。どのクラスの外にもメソッドを定義してから、 'friend'の後にあなたが望むクラスの最初の行を追加してください。これは、子クラスを持つクラスでのみ機能しますが。 –

+0

この例は、メンバ関数 'getSomething'が定義されているクラスで動作します。これは外部コードから来るクラスで動作し、特定の階層でクラスを束縛しません。どのクラスにも関数 'print'を追加して、この関数を機能させたい場合には、これは役に立つかもしれません。 –

関連する問題