【问题标题】:How to create an overload for two already existing types?如何为两种已经存在的类型创建重载?
【发布时间】:2019-09-21 20:43:10
【问题描述】:

我目前正在尝试在 C++ 中模拟管道,您可以在其中通过管道将某些内容作为参数提供给 lambda 函数。

但是当我在操作符上创建全局重载 |在向量和函数指针之间,我无法重新定义运算符,因为(我假设)你不能重载两个原始类型。

这是我一直在尝试的:

#include <iostream>

using namespace std;

void operator |( int *vet , void(*func)(int)){
    for ( int i = 0 ; i < 10 < i++){
        func(vet[i]);
}

int main(int argc, char **argv)
{
    int tab[10] =  { 1, 2, 3, 2, 3, 4, 6, 0, 1, 8 };

    tab | []( int x ) { cout << x*x << endl; };

    return 0;
}

我得到的错误是“错误:'void operator|(int*, void (*)(int))' must have an argument of class or enumerated type”

那么,我将如何重载 |数组和 lambda 函数之间的运算符?

提前致谢。

【问题讨论】:

  • 考虑到| 运算符必须返回一个值,您的重载毫无意义。您无法真正改变运算符的基本方面。
  • 另外,你想要的已经通过std::for_each函数实现了(或者使用range-based for loop)。

标签: c++ operator-overloading


【解决方案1】:

标准中已经有一个很好的类表示函数对象:std::function。您可以使用它来满足运算符重载的要求(see it online):

#include <functional>

void operator |( int *vet , std::function<void(int)> func){
    for ( int i = 0 ; i < 10; i++){
        func(vet[i]);
    }
}

但是,您提出的语法确实很糟糕。对于任何了解 C++ 的读者来说,这显然是错误的。看到这个,我的第一个想法是“有人打错了,然后输入了 | 而不是 =。另外,类型在哪里?”。另外,您不能真正将其用作管道,因为您不返回任何内容。管道第二个调用将返回调用operator |(void, [function_type])

使用命名函数是可以忍受的:

auto squarePrinter = []( int x ) { cout << x*x << endl; };
tab | squarePrinter;

但它仍然令人困惑 - 它不是 Bash 代码,是吗?

最好和最易读的解决方案是使用标准中的知名函数和习语 - std::for_each,正如 Some Programmer Dude 所建议的,甚至是普通的 for 循环

#include <algorithm>

std::for_each(std::begin(tab), std::end(tab), []( int x ) { cout << x*x << endl; });

【讨论】:

  • 非常感谢,正是我想要的!至于语法,我同意它看起来很可怕,但这是我的任务,所以我不得不这样做
【解决方案2】:

提交我的答案后,我可以访问让我觉得有点愚蠢的解决方案,这里是:

#include <algorithm>
 void operator | ( const auto& v, auto map ) {
  for_each( begin( v ), end( v ), map );
}

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 2023-01-21
    • 2014-10-26
    • 2021-12-02
    • 2017-04-07
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    相关资源
    最近更新 更多