簡體   English   中英

在模板結構外部重載運算符

[英]Overloading operator outside template struct

我有以下代碼:

#include <iostream>
#include <stdio.h>
using namespace std;

template <class F>
struct CMPLX {

    F Re, Im;

    struct _printnice {
        F Re, Im;
        string sep;
        _printnice(const F& Re, const F& Im, const string& sep) : Re(Re), Im(Im), sep(sep) {}
    };

    CMPLX <F> (F Re, F Im) : Re(Re), Im(Im) {}

    _printnice PrintNice(const string& sep="\t"){
        return _printnice(Re, Im, sep);
    }

};

template<class F>
ostream& operator << (ostream& os, const CMPLX<F> c){
    cout << c.Re << " + " << c.Im << "i";
}

template<class F>
ostream& operator << (ostream& os, const CMPLX<F> :: _printnice p){
    cout << p.Re << p.sep << p.Im;
}

int main(){
    CMPLX<float> c(2.0,1.0);
    cout << c << endl;
    cout << c.PrintNice() << endl;

}

我介紹了一個子結構_printnice ,以便重載運算符<<並具有不同格式的CMPLX類輸出。 但是,這會在'p'之前拋出一個錯誤預期的unqualified-id ,我不知道如何解決這個問題(我對模板的了解非常有限)。

我嘗試將<<的第二個定義更改為以下哪個有效,但我必須指定類型,這是皺眉的:

ostream& operator << (ostream& os, const CMPLX <float> :: _printnice p){
    cout << p.Re << p.sep << p.Im;
}

您的方法有兩個問題。 首先, _printnice是一個依賴名稱,因此您需要添加一個額外的typename 如果這個問題得到解決,你最終會得到:

template<class F>
ostream& operator << (ostream& os, typename CMPLX<F>::_printnice const & p)

正如Dietmar在之前的回答中指出的那樣,這段代碼的問題在於F處於不可推導的環境中,這將失敗。

一個簡單的解決方案是在_printnice代碼的范圍內定義運算符,其中typename

template <class F>
struct CMPLX {
   //...
   struct _printnice {
      friend std::ostream& operator<<( std::ostream& o, _printnice const & p ) {
         // print here
         return o;
      }
   }
   //...
};

_printnice的定義中,已知類型是類型,因此不再需要typename 重載的operator<<將由Argument Dependent Lookup找到,並且因為它引用了該類型的特定實例化,所以沒有要推導的模板參數。

在功能中:

template <typename F>
std::ostream& operator<<( std::ostream& os, CMPLX<F>::_printnice p);

F不是在可推斷的背景下。 (見§14.8.2.5。)

NB。 這不是答案。 大衛已經回答了。 FWIW,只是解決了一些問題,因此它可以在gcc 4.72下編譯和運行。

#include <iostream>
#include <stdio.h>
using namespace std;

template <class F>
struct CMPLX {

    F Re, Im;

    struct _printnice {

        F Re, Im;
        string sep;
        _printnice(const F& Re, const F& Im, const string& sep) : Re(Re), Im(Im), sep(sep) {}

        friend ostream& operator << (ostream& os, const _printnice& p){
            cout << p.Re << p.sep << p.Im;
            return os;
        }
    };

    CMPLX <F> (F Re, F Im) : Re(Re), Im(Im) {}

    _printnice PrintNice(const string& sep="\t"){
        return _printnice(Re, Im, sep);
    }

};

template<class F>
ostream& operator << (ostream& os, const CMPLX<F> c){
    cout << c.Re << " + " << c.Im << "i";
    return os;
}

int main() {
    CMPLX<float> c(2.0,1.0);
    cout << c << endl;
    cout << c.PrintNice() << endl;
}

//result
/*
2 + 1i
2       1
*/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM