我有自己的类,我在其中定义和使用<<像这样的运算符:
vw& vw::operator<<(const int &a) { // add a to an internal buffer // do some work when it's the last number return *this; } ... vw inst; inst << a << b << c << d; ... inst << a << b; ...
链的数量<<每次通话都不一样.这些数字一起代表一个代码,我需要在代码完成时做一些事情. 我还有其他选择可以知道它何时完成,而不是为每个链添加一个特殊的终止值,如下所示?
inst << a << b << c << d << term; ... inst << a << b << term;
EDIT2:遵循LogicStuff的当前解决方案:
--- chain.h --- #pragma once #include <iostream> class chain { public: chain(); ~chain(); }; --- chain_cutter.h --- #pragma once #include "chain.h" class chain_cutter { chain &inst; public: explicit chain_cutter(chain &inst) : inst(inst) { std::cout << "cutter_constructor" << std::endl; } ~chain_cutter(); }; --- chain_cutter.cpp --- #include "stdafx.h" #include "chain_cutter.h" chain_cutter::~chain_cutter() { std::cout << "cutter_destructor" << std::endl; } --- chain.cpp --- #include "stdafx.h" #include "chain.h" chain::chain() { std::cout << std::endl << "chain_constructor" << std::endl; } chain::~chain() { std::cout << std::endl << "chain_destructor" << std::endl; } --- flowchart.cpp --- #include "stdafx.h" #include <iostream> #include "chain.h" #include "chain_cutter.h" chain_cutter operator<<(chain &inst,const int &a) { chain_cutter cutter(inst); std::cout << a << std::endl; return cutter; } chain_cutter&& operator<<(chain_cutter &&cutter,const int &a) { std::cout << a << std::endl; return std::move(cutter); } int main() { std::cout << "main start" << std::endl; chain ch; ch << 1 << 2 << 3; std::cout << std::endl << "-----" << std::endl; ch << 4 << 5; return 0; }
这是输出:
main start chain_constructor cutter_constructor 1 2 3 cutter_destructor ----- cutter_constructor 4 5 cutter_destructor
解决方法
可以在不改变当前语法的情况下实现.
你将不得不使inst<< a(即当前运算符<<)返回“特殊”类的临时实例,保持对inst的引用,实现运算符<<通过调用inst.operator<< ;,返回引用
to * this,然后在析构函数中执行额外的工作,这将在语句的末尾调用.
是的,您可以使用它跟踪通话计数.
我建议这些nonmember运算符<<重载(vw_chain是新的代理类):
// Left-most operator<< call matches this vw_chain operator<<(vw &inst,const int &a) { return vw_chain(inst,a); } // All subsequent calls within the << chain match this vw_chain &&operator<<(vw_chain &&chain,const int &a) { chain.insert(a); return std::move(chain); }
班级本身:
struct vw_chain { explicit vw_chain(vw &inst,const int &a) : inst(inst) { insert(a); } ~vw_chain() { // do something } void insert(const int &a) { // This,the original operator<<,should be made accessible only to this // function (private,friend class declaration?),not to cause ambiguity. // Or,perhaps,put the implementation of the original operator<< here // and remove it altogether. inst << a; ++insertion_count; } vw &inst; size_t insertion_count = 0; };
我们必须通过rvalue引用传递实例.我们在vw_chain的构造函数中进行第一次插入,以获得mandatory copy elision(C 17),它仅适用于prvalues.是否会在返回声明中完成复制,未使用NRVO和旧标准进行指定.我们不应该依赖于此.
Pre-C 17解决方案:
struct vw_chain { // We keep the constructor simpler vw_chain(vw &inst) : inst(inst) {} // Moved-from chains are disabled vw_chain(vw_chain &&other) : inst(other.inst),insertion_count(other.insertion_count) { other.is_enabled = false; } // And will not call the termination logic ~vw_chain() { if(is_enabled) { // do something } } void insert(const int &a) { inst << a; ++insertion_count; } vw &inst; size_t insertion_count = 0; bool is_enabled = true; }; // The first overload changes to this vw_chain operator<<(vw &inst,const int &a) { vw_chain chain(inst); chain.insert(a); return chain; }