我有自己的类,我定义并使用<<运算符,如下所示:
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;
...
Run Code Online (Sandbox Code Playgroud)
链<<的数量每次都不同.这些数字一起代表一个代码,我需要在代码完成时做一些事情.
我还有其他选择可以知道它何时完成,而不是为每个链添加一个特殊的终止值,如下所示?
inst << a << b << c << d << term;
...
inst << a << b << term;
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
main start
chain_constructor
cutter_constructor
1
2
3
cutter_destructor
-----
cutter_constructor
4
5
cutter_destructor
Run Code Online (Sandbox Code Playgroud)
可以在不改变当前语法的情况下实现.
你必须使inst << a(即当前operator<<)返回一个"特殊"类的临时实例,持有一个引用inst,operator<<通过调用实现inst.operator<<,返回引用*this,然后在它的析构函数中执行额外的工作,这将在声明的结尾.
是的,你可以跟踪它的通话次数.
我建议这些非成员 operator<<重载(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);
}
Run Code Online (Sandbox Code Playgroud)
班级本身:
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;
};
Run Code Online (Sandbox Code Playgroud)
我们必须通过rvalue引用传递实例.我们在vw_chain构造函数中进行第一次插入,以获得强制复制省略(C++ 17),它只适用于prvalues.是否会在return声明中完成复制,未使用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;
}
Run Code Online (Sandbox Code Playgroud)
您可以:
使用特殊的最终类型来表示终止(a la std::endl).
避免使用operator<<和定义可变参数模板函数.可变参数模板函数支持任意数量的任意参数,并在编译时知道该数字.
将逻辑放入vw析构函数中,operator<<只允许使用rvalues.例如
vw{} << a << b << c;
// `vw::~vw()` contains termination logic
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |