我有以下代码:
#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'之前预期的nonqualified-id ,我不知道如何解决这个问题(我对模板的了解非常有限)。
我尝试将<<
的第二个定义更改为以下有效的定义,但我必须指定类型,这是不赞成的:
ostream& operator << (ostream& os, const CMPLX <float> :: _printnice p){
cout << p.Re << p.sep << p.Im;
}
答案 0 :(得分:4)
您的方法存在两个问题。首先,_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
。 Argument Dependent Lookup将找到重载的operator<<
,并且因为它引用了该类型的特定实例化,所以没有要推导的模板参数。
答案 1 :(得分:1)
在功能中:
template <typename F>
std::ostream& operator<<( std::ostream& os, CMPLX<F>::_printnice p);
F
并非处于可推断的背景下。 (见§14.8.2.5。)
答案 2 :(得分:0)
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
*/