在 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/