好吧,我想知道为什么endd
似乎没有执行(虽然它在编译时不会产生任何错误)。
struct dxfDato
{
dxfDato(int c, string v = 0, int t = 0) { codigo = c; valor = v; tipo = t; }
dxfDato() { }
int tipo;
int codigo;
string valor;
};
class dxfItem
{
private:
std::ostringstream ss;
typedef std::ostream& (*manip)(std::ostream&);
public:
int clase;
string valor;
vector<dxfDato> datos;
vector<dxfItem> hijos;
template <typename T>
dxfItem& operator<<(const T& x)
{
ss << x;
return *this;
}
dxfItem& operator<<(manip x) // to store std manipulators
{
ss << x;
return *this;
}
static dxfItem& endd(dxfItem& i) // specific manipulator 'endd'
{
dxfDato dd;
dd.valor = i.ss.str();
i.datos.push_back(dd);
std::cout << "endd found!" << endl;
return i;
}
};
/* blah blah blah */
dxfItem header;
header
<< 9 << endl << "$ACADVER" << endl << 1 << endl << "AC1500" << endl
<< dxfItem::endd // this apparently doesn't execute anything
<< "other data" << endl
;
这是我在尝试开发某些东西时发现的最后一个问题。最后一件事暴露在这里:C++ Operator overloading example
谢谢大家!
答案 0 :(得分:4)
您已将类型manip
定义为按引用获取std::ostream
并按引用返回std::ostream
的函数,但您已定义endd
一个dxfItem
并返回dxfItem
而dxfItem
并非来自std::ostream
。
由于此类型不匹配,编译器正在生成对operator<<
模板的调用,而不是manip
重载。
<击>
此外,您的manip
重载需要实际调用传递给它的操纵器函数:
dxfItem& operator<<(manip x)
{
x(ss);
return *this;
}
击> <击> 撞击>
答案 1 :(得分:1)
尝试执行endd
时使用的语法使我认为您希望将其用作endl
。 endl
是一个特殊的构造,称为操纵器。你可以构建自己的操纵器,但这不是一个胆小的主题(也不适合初学者)。
(无论如何,如果你仍想让endd
成为一个操纵者,请谷歌搜索“C ++流操纵器教程”......)
答案 2 :(得分:1)
要被称为操纵者,您的函数应该具有类型std::ostream& (*)(std::ostream& strm)
。
请注意,当前C ++中不允许使用参数定义您自己的操纵器。
答案 3 :(得分:1)
同意Adrien Plisson建议以了解有关操纵者的更多信息,我可以向您展示如何实现我想要的目标:
typedef dxfItem& (*noArgdxfManip)(dxfItem &); // here is the type for your manipulator
dxfItem & operator << (noArgdxfManip manip)
{
return manip(*this);
}
如果您能理解这段代码,您就可以理解操纵器的工作原理。通常,如果流看到一个函数指针传递给它&lt;&lt;运算符,它只是尝试打印其内容。但是对于在流和返回流上操作的函数指针存在重载,而不是在流上打印指针调用指向函数。在这里,您对dxfItem类执行相同的操作。
<强>声明强> 我没有尝试编译它,因此它可能包含一些语法错误。
答案 4 :(得分:1)
如前所述,标准流使用重载运算符&lt;&lt;它接受一个操纵器类型的函数指针,然后调用该操纵器来实现该行为。
typedef和重载运算符&lt;&lt;您提供的应该允许您使用标准操纵器,因为预期的功能接受并返回ostream&amp;。
您没有声明重载运算符&lt;&lt;它接受一个接受并返回dxfItem&amp;的函数的函数指针,因此它将使用默认运算符&lt;&lt;它应该只存储/打印函数的地址而不是执行操作符。
您需要为操纵器设置typedef:
typedef dxfItem& (*endd_manip)(dxfItem&);
然后你可以创建一个重载的运算符&lt;&lt;为它:
dxfItem& operator<<(endd_manip x)
{
// Call the manipulator on the stream.
x(*this);
return *this;
}
答案 5 :(得分:0)
我认为我的问题就是这一行
<< dxfItem::endd // this apparently doesn't execute anything
应该是这样的
<< dxfItem::endd(Whatever argument goes in here)
答案 6 :(得分:-1)
C ++语言(以及C语言)中的函数由函数调用操作符()
调用(“执行”)(它也可以为函数提供参数)。我没有看到代码中的任何函数调用操作符直接或间接地应用于endd
函数。这就是它永远不会被执行的原因。