模板结构外部的重载运算符
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"之前预期非限定 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<<
将由参数相关查找找到,并且由于它引用了类型的此特定实例化,因此没有要推断的模板参数。
在函数中:
template <typename F>
std::ostream& operator<<( std::ostream& os, CMPLX<F>::_printnice p);
F
并非不在可推导的上下文中。 (参见 §14.8.2.5。
注意。这不是一个答案。大卫已经回答了。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
*/
相关文章:
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用