c++ - 检测运算符 << 序列的结尾

标签 c++ operator-overloading sequence terminator

在 C++ 中,如何以编程方式检测以下形式的序列的结尾:

object << argument1 << argument2 << argument3;

假设我像这样重载了运算符<<

Object& operator<<(Object& object, Argument& argument) {
...
}

上面的表达式将被这样计算:

(((object << argument1) << argument2) << argument3);

为了论证,我们假设对象是一个记录器。我将数据流式传输到记录器中。一旦最后一个参数(在本例中为 argument3,但参数的数量当然不固定)被流式传输到对象中,我希望对象组装消息并将其发布。我怎样才能做到这一点而不必写这样的东西:

object << argument1 << argument2 << argument3 << EOM;

谢谢。欢迎任何输入。

最佳答案

正如其他答案所提到的,使用“消息结束”标记是一个很好的设计。

但是如果你真的需要你要求的东西,你可以这样做:你像往常一样实现 EOM 想法,然后添加这个类:

class AutoEnd
{
private:
    mutable Object & m_obj;

public:
    explicit AutoEnd (Object & obj) : m_obj (obj) {}
    ~AutoEnd () {m_obj << EOM;}

    Object & obj () const {return m_obj;}
};

template <typename T>
AutoEnd const & operator << (AutoEnd const & ae, T && arg)
{
    ae.obj() << std::forward<T>(arg);
    return ae;
}

你可以这样使用它:

Object object;
...
AutoEnd(object) << argument1 << argument2 << argument3;

这会做你想做的。一些注意事项:

  • 你显然仍然可以使用明确的 EOM添加AutoEnd后的方法.这使您可以更灵活地使用任何有意义的方法。
  • 这项技术的关键是 AutoEnd 的析构函数,将在实例化它的行的末尾调用。
  • 你可以比上面更好地实现它。最重要的是,制作 AutoEnd 的构造函数是个好主意。私有(private)或以某种方式向用户发出信号,表明他们不应创建 AutoEnd 的正常实例,因为它们那样没用,而且它们会保留对您的引用 Object s 并可能会在它们被销毁后尝试使用它们。
  • 只有在 operator << 的情况下,您才能安全地使用此技术。对于 Object不会抛出异常,因为它是在析构函数内部调用的,析构函数不应抛出
  • AutoEnd旨在用作临时对象,您只能使用 const &轻松处理临时对象,operator <<获取并返回一个常量引用,以及存储的 Object引用声明为 mutable .在我看来,这不是一个糟糕的设计,因为 AutoEnd对象没有任何内部状态(除了 Object & )和调用 operator << 的正确性关于这一点需要在其他地方得到保证(即 AutoEnd 不需要关心这一点。)
  • 你应该制作AutoEnd不可复制。

关于c++ - 检测运算符 << 序列的结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17130942/

相关文章:

c++ - 我的标准偏差程序的输出问题

c++ - C++ 中运算符 << 的重写

c++ - 使 operator<< 成为虚拟的?

sql - 在多个函数之间创建序列

c++ - 如何在 C++ 中重新启动循环(在随机运行中查找唯一序列)

machine-learning - 在生物文本数据中应用机器学习

c++ - QT没有这样的插槽

c++ - Opencv: 'centers' 参数在 cv::kmeans 中如何工作?

c++ string::size 中的 CharT 元素是什么?

c++ - 访问包含它的 vector 元素时,类对象的运算符重载不起作用?