重载按位 OR('|'),用于链接操作无法按预期工作
Overloading bitwise OR('|') for chaining operations not working as expected
我正在尝试超负荷位或'|'运算符,以便我可以一个接一个地链接不同的操作。
我已经实施了以下代码。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Test
{
explicit Test(vector<int> vdata) : data_(vdata) { }
vector<int>& operator()()
{
return data_;
}
template<typename Pred>
Test operator | (Pred P)
{
*this = P;
return *this;
}
vector<int> data_;
};
template <typename Con, typename Pred>
Con Transform(Con& C, Pred P)
{
vector<int> res;
transform(begin(C()), end(C()),back_inserter(res), P);
return Con(res);
}
template <typename Con, typename Pred>
Con Filter(Con& C, Pred P)
{
vector<int> res;
remove_copy_if(begin(C()), end(C()), back_inserter(res), P);
return Con(res);
}
int main()
{
vector<int> vdata{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
auto DoubleIt = [](int& v) {
return v *= 2;
};
auto Remove_Lteq4 = [](auto v) {
return v <= 4;
};
auto Remove_divideby3=[](auto v)
{
return !(v % 3);
};
Test test(vdata);
Test test1 =
test | Filter(test, Remove_Lteq4) |
Transform(test, DoubleIt) |
Filter(test, Remove_divideby3);
// output
for (auto v : test1())
cout << v << " ";
}
该代码在CXXDROID上提供预期输出2.0_arm离线编译器,C 14/C 17,但我在在线编译器上获得了不同的结果
输入:vector = {1,2,3,4,5,6,7,8,9,10,11,12}采用序列的操作是滤波器值&lt; = 4然后将剩余的乘以2,然后滤波值可除以3
结果离线编译器(CXXDROID(预期输出:10、14、16、20、22实际输出:10、14、16、20、22
在线编译器实际输出:1,2,4,5,7,8,10,11(实际上,这是只有将remove_divideby3函数应用于输入时,您将获得的输出(。
我现在正在挣扎一段时间,无法找出不同输出的原因。有人可以告诉我在哪里犯错。如果我一次仅应用一项操作,则该代码正常工作。
如果有人可以回答加法问题,我也会非常好。
我需要编写复制构造函数/复制分配,移动构造函数和移动分配。
是我对对象的使用情况,可以按值和参考来传递和返回对象。我认为问题在这里的某个地方,可能会通过一个需要参考的对象。
是否需要超载'|'在全球级别。
注意:使用命名空间std;仅在我在移动设备上键入代码时才用于方便目的。
谢谢
template<class F>
struct pipe_func {
F f;
template<class Lhs>
friend auto operator|( Lhs&& lhs, pipe_func rhs ) {
return rhs.f( std::forward<Lhs>(lhs) );
}
};
template<class F>
pipe_func(F)->pipe_func<F>;
有一个适合您的基础。pipe_target
采用一个函数,当管道事物将其馈送到功能并返回结果时。
现在假设您要编写过滤器。
template<class Pred>
auto Filter( Pred p ) {
return pipe_func{[p]( auto&& container ) {
using std::begin; using std::end;
using R = std::decay_t< decltype(container) >;
R retval;
std::remove_copy_if( begin(container), end(container), std::back_inserter(retval), p );
return retval;
}};
}
因此,filter
是一个依据的函数。
它返回pipe_func
。pipe_func
中有一个应用谓词的lambda。
转换是相似的:
template<class Pred>
auto Transform( Pred p ) {
return pipe_func{[p]( auto&& container ) {
using std::begin; using std::end;
using R = std::decay_t< decltype(container) >;
R retval;
std::transform( begin(container), end(container), std::back_inserter(retval), p );
return retval;
}};
}
测试代码看起来像:
std::vector<int> test1 =
vdata | Filter(Remove_Lteq4) |
Transform(DoubleIt) |
Filter(Remove_divideby3);
现场示例。
现在,一种解决方案,我们可以将两个参数的功能输入功能有点腥。该功能仍然认为它需要2个参数,因此将其传递第二个很棘手。
我会避免它。任何解决方案都将是黑客。
您正在这样做(我重新布置了管道以使其更容易阅读(:
Test test1 =
test | Filter(test, Remove_Lteq4)
| Transform(test, DoubleIt)
| Filter(test, Remove_divideby3);
让我们从后面开始。Filter(test, Remove_divideby3)
做什么?它还给一个容器,该容器是满足Remove_divideby3
的test
的所有元素。但是test
是您开始的,它不取决于此操作的任何部分。其他Filter
或Transform
返回什么都没关系,因为这些值都没有用作 Filter
的输入。
这就是为什么您得到的东西与写作没有什么不同:
Test test1 = Filter(test, Remove_divideby3);
您的适配器具有将范围作为参数:
Filter(Transform(Filter(test, Remove_Lteq4), DoubleIt), Remove_divideby3)
或使用管道:
test | Filter(Remove_Lteq4) | Transform(DoubleIt) | Filter(Remove_divideby3)
不是同时同时。
- 为什么在popback()操作之后,它仍然打印完整的矢量
- QSqlquery prepare()和bindvalue()不工作
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- 使 Flutter C/C++ 互操作示例正常工作
- 异步操作的 Asio 处理程序在其同步对应项正常工作时不会调用
- 重载按位 OR('|'),用于链接操作无法按预期工作
- 为什么我的文件/目录操作在Windows上工作正常,但在Linux上不能
- 无法获得新的 tf。在 Tensorflow 中的 Python shell 中工作的操作
- 此数组操作在C++中如何工作
- 这种按位操作是如何工作的
- 类复制操作,它是如何工作的
- 在boost MPL中,如何检查操作是否按预期工作
- 指针上的此操作如何工作
- 设置自定义对象不工作的操作
- 前缀(++x)和后缀(++ +)操作是如何工作的
- 栈push操作实现不工作
- 为什么此内联程序集中的错误操作无法正常工作
- 为什么提取操作不工作
- 由于在返回语句中使用了布尔或操作,因此递归如何对以下代码工作
- BSF操作码不工作