C++运算符重载模仿管道操作

重载 + 运算

实现+运算重载

通过类内部实现成员函数operator+​以重载成员运算符+​,并接受一个右操作数为int​类型。返回自己的引用。

class A
{
public:
    A(int v) : _v(v)
    {}
    A& operator+(int v)
    {
        _v += v;
        return *this;
    }
    A& operator+(const A& rhs)
    {
        _v += rhs._v;
        return *this;
    }
private:
    int _v = 0;
};

int main()
{
    A a(1);
    (a + 1) + a; // 4
    return 0;
}

首先程序进行计算a+1​返回A类型,然后进行(a+a)

那么考虑一个问题,我们的类型A​的加法支持交换律吗,也就是

(1 + a) + a;//?

显然不支持。因为我们没有定义一个做操作数为数字而有操作数是类型A​的行为,那么如何解决呢?

友元函数

一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数,类中定义的友元函数,它不是成员函数,但它拥有成员函数的访问权限。基本定义格式如下:

    friend int operator+(int lhs, const A& rhs)
    {
        // 访问类成员
        return lhs + rhs._v;
    }

使用成员函数重载运算符时,第一个操作数通过this指针隐式地传递,而友元函数不是成员函数,所以要有两个参数且是显示的传递。

完整代码如下:

class A
{
public:
    A(int v) : _v(v)
    {}
    A& operator+(int v)
    {
        _v += v;
        return *this;
    }
    A& operator+(const A& rhs)
    {
        _v += rhs._v;
        return *this;
    }
    friend int operator+(int lhs, const A& rhs)
    {
        // 访问类成员
        return lhs + rhs._v;
    }
private:
    int _v = 0;
};

int main()
{
    A a(1);
    int v = (1 + a) + a;
    return 0;
}

全局运算符重载探索

我们只是简仿C++20​的ranges​操作,不要用于实际。

我们想实现一个功能,类似与管道操作符,对一个字符串的一个操作的结果能给下一个使用。比如:

#include <iostream>
#include <ranges>
#include <vector>

#include <ranges>
#include <iostream>

template <typename T, typename F>
std::vector<T> operator|(std::vector<T> vec, F &&f)
{
    return f(vec);
}

namespace views
{
    template <typename F>
    class filter
    {
    public:
        filter(const F &f) : f_(f)
        {
        }

        std::vector<int> operator()(const std::vector<int> &data)
        {
            std::vector<int> new_data;
            for (const auto &d : data)
            {
                if (f_(d))
                {
                    new_data.push_back(d);
                }
            }
            return new_data;
        }

    private:
        const F &f_;
    };

    template <typename F>
    class transform
    {
    public:
        transform(const F &f) : f_(f)
        {
        }

        std::vector<int> operator()(const std::vector<int> &data)
        {
            std::vector<int> new_data;
            for (const auto &d : data)
            {
                new_data.push_back(f_(d));
            }
            return new_data;
        }

    private:
        const F &f_;
    };
}

int main()
{
    auto even = [](int i)
    { return 0 == i % 2; };
    auto square = [](int i)
    { return i * i; };

    std::vector<int> data = {0, 1, 2, 3, 4, 5};
    const auto ret = data | views::filter(even) | views::transform(square);
    // const auto ret = data | [even](const std::vector<int> &data)
    // {
    //     std::vector<int> new_data;
    //     for (const auto &d : data)
    //     {
    //         if (even(d))
    //         {
    //             new_data.push_back(d);
    //         }
    //     }
    //     return new_data;
    // };

    for (const auto &d : ret)
    {
        std::cout << d << " ";
    }
    return 0;
    // 组合视图的“管道”语法:
    // for (int i : data | std::views::filter(even) | std::views::transform(square)) {
    //     std::cout << i << ' ';
    // }

    // std::cout << '\n';

    // // 传统的“函数式”组合语法:
    // for (int i : std::views::transform(std::views::filter(data, even), square)) {
    //     std::cout << i << ' ';
    // }
}
posted @ 2023-10-03 19:32  天空之城00  阅读(32)  评论(0)    收藏  举报