(プログラミングの割り当てとして) 作成したテンプレート化されたスタック クラスの出力ストリーム演算子 (<<) をオーバーロードしようとしています。私は、フレンド operator<< 関数をスタック クラスに宣言するという通常のパラダイムを使用しています。「テンプレート フレンド関数をテンプレート クラスにバインドする」という Prata の例 (C++ プライマー プラス) に従いました。コードはコンパイルおよび実行されますが、テンプレート化された operator<< 関数が main の出力ストリーム演算子のすべての出現をオーバーロードしようとしているため、 Stack クラスの出力ストリーム演算子のみをオーバーロードする必要があるため、目的の結果が得られません。 . したがって、オーバーロードされた operator<< 関数を特殊化する必要があると思います。
問題を示すために、より単純なコード例を作成しました。この例では、オーバーロードされた operator<< を使用するのではなく、"oper()" という関数を使用していることに注意してください。コードは次のとおりです (これも添付されています)。問題は、oper() が Bigger クラス (必要なクラス) と BIG クラス (不要なクラス) の両方で機能することです。テンプレート化された oper() 関数を特殊化する方法を教えてもらえますか?
// Compiler: gcc
// Purpose: test templates. test bound template friend fns.
#include <iostream>
using namespace std;
// declare template function
template <typename T> std::ostream & oper (std::ostream &os, const T &);
template <typename T> class Bigger {
T value;
public:
Bigger(T init) {value = init;}
// declare bound template friend functions
friend std::ostream &oper<> (std::ostream &os, const Bigger<T> &);
};
class Bad { // but oper() can work with this class too!
int i;
public:
int value;
Bad(): i(1),value(2) {};
};
// define full template functions
// want to specialize this function so that it only works with class Bigger!
template <typename T> std::ostream &oper (std::ostream &os, const T & big) {
os << big.value;
return os;
}
int main (int argc, char * argv[]) {
Bigger <float> bf {3.1};
// this is desired behavior. oper() acts as a friend to Bigger.
cout << "oper bf: "; oper(cout,bf); cout<<endl;
Bad bad;
// this is undesired behavior. template is too loose allowing oper to work for Bad!!!
cout << "oper bad: ";oper(cout,bad);cout<<endl;
return 0;
}