4

私はテンプレートが大好きです。少なくとも、テンプレートを理解できれば好きです ;-)。テンプレートを使用して、オーバーロードされた演算子を実装しました。私は今、関数呼び出しを特化しようとしています。

これが私がすることです:

class Terminallog {
public:

    Terminallog();
    Terminallog(int);
    virtual ~Terminallog();

    template <class T>
    Terminallog & operator<<(const T &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> *v);
    template <class T, size_t n>
    Terminallog & operator<<(const T(&v)[n]);
    Terminallog & operator<<(std::ostream&(*f)(std::ostream&));
    Terminallog & operator<<(const char v[]);

    //stripped code

};

//stripped code

template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
    if (this->lineendet == true) {
        this->indent();
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> &v) {
    for (unsigned int i = 0; i < v.size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v.at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> *v) {
    for (unsigned int i = 0; i < v->size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v->at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T, size_t n>
Terminallog &Terminallog::operator<<(const T(&v)[n]) {
    unsigned int elements = sizeof (v) / sizeof (v[0]);
    for (unsigned int i = 0; i < elements; i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v[i];
    }
    std::cout << std::flush;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(std::ostream&(*f)(std::ostream&)) {
    if (f == static_cast<std::ostream & (*)(std::ostream&)> (std::endl)) {
        this->lineendet = true;
    }
    std::cout << f;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(const char v[]) {
    if (this->lineendet == true) {
        std::cout << std::endl;
        this->indent();
        std::cout << v;
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

//sripped code

今、私は次のようなことを試みています

vector<int> *test3 = new vector<int>;
    test3->push_back(1);
    test3->push_back(2);
    test3->push_back(3);
    test3->push_back(4);

Terminallog clog(3);
clog << test3;

これは問題なくコンパイルされます。ただし、コードを実行すると、すべての要素ではなく、test3 のアドレスが出力されます。コンパイラは次のように考えていると結論付けます。

Terminallog & operator<<(const T &v);

より良い一致です。しかし、私はそれについて何をすべきかわかりません。私のコードのどこに間違いがありますか? なぜですか

Terminallog & operator<<(const std::vector<T> *v);

呼んだことない?

4

2 に答える 2

5

test3コード内の の型はですが、その型の引数を取るものstd::vector<int> *はありません。Terminallog::operator<<取るものがconst std::vector<int> *あり、そうすると呼び出されます

clog << const_cast<const vector<int>*>(test3);

ちなみに、ベクトルを新しくすることは、ほとんど良い考えではありません。

于 2011-03-29T13:10:58.637 に答える
4

これを const-to-const-vector バージョンと一致させるには、型に const を追加する必要があり、これは最上位の const (const-pointer-to-vector、つまりstd::vector<T>* const) ではありません。選択されたオーバーロードは型変換を必要とせず、より適切に一致します。

ポインターのオーバーロードを完全に削除することをお勧めします。特に、ベクター参照のオーバーロードが複製されているだけであることを確認してください。代わりに、ポインターを逆参照します。

clog << *test3;
于 2011-03-29T13:14:53.037 に答える