C ++操纵器未被执行

时间:2010-02-04 14:50:51

标签: c++

好吧,我想知道为什么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

谢谢大家!

7 个答案:

答案 0 :(得分:4)

您已将类型manip定义为按引用获取std::ostream并按引用返回std::ostream的函数,但您已定义endd一个dxfItem并返回dxfItemdxfItem并非来自std::ostream

由于此类型不匹配,编译器正在生成对operator<<模板的调用,而不是manip重载。

<击> 此外,您的manip重载需要实际调用传递给它的操纵器函数:

dxfItem& operator<<(manip x)
{
   x(ss);
   return *this;
}

<击>

答案 1 :(得分:1)

尝试执行endd时使用的语法使我认为您希望将其用作endlendl是一个特殊的构造,称为操纵器。你可以构建自己的操纵器,但这不是一个胆小的主题(也不适合初学者)。

(无论如何,如果你仍想让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函数。这就是它永远不会被执行的原因。