【发布时间】:2020-11-11 12:02:51
【问题描述】:
我试图弄清楚如何为给定的基类对象一般地重载operator|() 以序列化或链接类似于pipes 或operator<<() 工作方式的函数调用...我想通过管道运算符链接它们......这样我可以拥有一系列独立的函数,并在单个数据对象上调用它们......换句话说,对相同的数据类型执行多个转换,就像在流系统...
考虑以下伪代码示例: 这段代码可能无法编译,我没有方便的编译器,而且我可能在函数指针或函数对象中使用了错误的语法作为运算符中的参数......这只是为了说明模式和行为我在追。
template<typename T>
typedef T(*Func)(T); // Function Pointer for functors-lambdas-etc...
template<typename T>
struct pipe_object {
T operator|(T(*Func)(T) func) {
return func(T);
}
T operator()(T(*Func)(T) func) {
return this->operator|(t, func);
}
};
那么我可能想像这样使用它们:
constexpr int add_one_f(int x) {
return (x+1);
}
constexpr int add_two_f(int x) {
return (x+2);
}
void foo() {
pipe_object<int> p1 = {};
pipe_object<int> p2 = {};
int result = p1(&add_one) | p2(&add_two);
// or something like...
int result = p1 | p2; // ... etc ...
// or something like:
p1 = add_one | add_two | p2; // ... etc ...
}
我只是不知道如何在|() 运算符中传播intput - output... 我是否必须重载两个版本才能识别|(lhs, rhs) 和|(rhs, lhs) ?
不仅如此,如果我想扩展它以便我的 functors 或 lambdas 接受多个参数怎么办...
我一直在对此进行 Google 搜索,只找到了一些资源,但没有任何具体、简单、优雅且至少具有 C++17 功能的最新资源...
如果您知道有关此主题的任何好的源材料,请告诉我!
【问题讨论】:
-
@IgorTandetnik 我知道,这只是伪代码......我没有我的编译器方便 atm......但目的是采用像对象这样的函子......或者可能是一个值和一个函子...
-
您的所有使用示例对我来说都没有多大意义。
result的值到底应该是多少?你添加一两个到是什么?p1和p2应该扮演什么角色? -
@Ignor 考虑像二维向量这样的对象...假设它已经填充了值...例如
vec2 v2 = {3,5}...然后我希望能够做点什么比如:v2 = rotate(30) | scale(5) | translate(15);然后它会将其旋转 30 度或弧度,将其缩放 5 个单位,然后平移 15...几乎类似于linux's pipes的工作方式... -
你控制
vec2的定义吗?你能给它一个赋值运算符来接受一个代表这个转换序列的expression template对象吗? -
那么 a) 你可能想把你的实际激励例子放在问题中,因为你现在所拥有的没有意义,并且 b) 就像我说的那样,你正在寻找的技术是称为“表达式模板”。如果您搜索它,您应该会找到一些示例。
标签: c++ operator-overloading c++17 chaining pipelining