1

(プログラミングの割り当てとして) 作成したテンプレート化されたスタック クラスの出力ストリーム演算子 (<<) をオーバーロードしようとしています。私は、フレンド 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;
}
4

2 に答える 2