4
4

3 に答える 3

4

あなたのアプローチには2つの問題があります。1 つ目は_printnice、従属名であるため、余分な を追加する必要があることですtypename。それが修正された場合、次のようになります。

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

このコードの問題は、Dietmar が以前の回答で指摘したように、F推測できないコンテキストにあるため、失敗することです。

_printnice簡単な解決策の 1 つは、コードのスコープ内で演算子を定義すること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 によって検出され、型のこの特定のインスタンス化を参照するため、推測するテンプレート引数はありません。

于 2012-10-15T17:06:39.127 に答える
1

関数内:

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

F推論可能なコンテキストではありません。(§14.8.2.5を参照してください。)

于 2012-10-15T16:59:25.927 に答える
0

注意。これは答えではありません。デビッドはすでにそれに答えました。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
*/
于 2012-10-15T17:29:40.013 に答える