You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

需求:扩展支持成员函数指针与back_inserter的std::transform包装器

扩展你的transform包装器以支持成员函数指针与back_inserter

我来帮你完善这个transform包装器,让它既能直接适配成员函数指针,又能兼容std::back_inserter这类输出迭代器,同时保留原有用法的简洁性。

现有基础实现回顾

先回顾你已经实现的核心包装逻辑,它帮我们省去了手动传入迭代器的繁琐:

template <typename C, typename C2, typename UnaryOperation>
void transform(const C& c1, C2& result, const UnaryOperation& up) {
    std::transform(std::begin(c1), std::end(c1), std::begin(result), up);
}

调用时只需传入容器和操作:

utils::transform(container, result, [](const auto& o) { return doSomething(o); });

新增支持成员函数指针与输出迭代器的重载

要实现需求,我们需要新增几个模板重载:一个适配成员函数指针,另一个兼容back_inserter这类输出迭代器(因为它返回的是迭代器对象,不是容器引用)。

完整扩展代码

#include <algorithm>
#include <iterator>
#include <functional>

namespace utils {
    // 原有版本:针对容器引用的输出
    template <typename C, typename C2, typename UnaryOperation>
    void transform(const C& c1, C2& result, const UnaryOperation& up) {
        std::transform(std::begin(c1), std::end(c1), std::begin(result), up);
    }

    // 新增:支持任意输出迭代器(包括back_inserter)的基础版本
    template <typename C, typename OutputIt, typename UnaryOperation>
    void transform(const C& c1, OutputIt result_it, const UnaryOperation& up) {
        std::transform(std::begin(c1), std::end(c1), result_it, up);
    }

    // 新增:适配无参成员函数指针 + 容器输出
    template <typename C, typename C2, typename Ret, typename T>
    void transform(const C& c1, C2& result, Ret (T::*mem_fn)()) {
        transform(c1, result, std::mem_fn(mem_fn));
    }

    // 新增:适配无参成员函数指针 + 输出迭代器(如back_inserter)
    template <typename C, typename OutputIt, typename Ret, typename T>
    void transform(const C& c1, OutputIt result_it, Ret (T::*mem_fn)()) {
        transform(c1, result_it, std::mem_fn(mem_fn));
    }

    // 新增:适配带参数的成员函数指针 + 容器输出
    template <typename C, typename C2, typename Ret, typename T, typename... Args>
    void transform(const C& c1, C2& result, Ret (T::*mem_fn)(Args...), Args&&... args) {
        transform(c1, result, [mem_fn, args...](const T& obj) {
            return (obj.*mem_fn)(std::forward<Args>(args)...);
        });
    }

    // 新增:适配带参数的成员函数指针 + 输出迭代器
    template <typename C, typename OutputIt, typename Ret, typename T, typename... Args>
    void transform(const C& c1, OutputIt result_it, Ret (T::*mem_fn)(Args...), Args&&... args) {
        transform(c1, result_it, [mem_fn, args...](const T& obj) {
            return (obj.*mem_fn)(std::forward<Args>(args)...);
        });
    }
}

使用示例

1. 调用无参成员函数

假设我们有如下结构体:

#include <string>
struct Object {};
struct X {
    Object foo() {
        return Object{};
    }
};

现在可以直接传入成员函数指针,两种输出方式都支持:

#include <vector>
int main() {
    std::vector<X> xs;
    std::vector<Object> results;

    // 直接输出到容器
    utils::transform(xs, results, &X::foo);

    // 用back_inserter追加元素
    utils::transform(xs, std::back_inserter(results), &X::foo);
    return 0;
}

2. 调用带参数的成员函数

如果成员函数需要传入参数:

struct X {
    Object foo(const std::string& str, int num) {
        return Object{};
    }
};

调用时直接追加参数即可:

// 输出到容器
utils::transform(xs, results, &X::foo, "test", 42);

// 用back_inserter输出
utils::transform(xs, std::back_inserter(results), &X::foo, "test", 42);

关键逻辑说明

  • 用std::mem_fn把成员函数指针转换成通用可调用对象,无缝适配原有transform逻辑。
  • 新增的输出迭代器重载,让我们可以直接传入std::back_inserter、std::front_inserter等迭代器类型,无需修改容器版本的代码。
  • 可变参数版本通过完美转发保证参数传递的效率和正确性,支持任意参数数量的成员函数。

内容的提问来源于stack exchange,提问作者Maxime Roussin-Bélanger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:57:10