需求:扩展支持成员函数指针与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
相关产品推荐
相关产品推荐

