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

C++20中如何传递需作为模板类型成员函数的函数?

可以在C++20中实现你的需求

根据你的场景,有两种主流实现方式,分别对应“指定现有成员函数”和“传入自定义lambda/可调用对象”的需求:

方案一:传入成员函数指针作为模板参数

如果你只是想灵活指定要调用T类的某个已有成员函数,可以把成员函数指针作为Manager的额外模板参数,语法上最接近你想要的type.FUNC()形式:

#include <iostream>

class Ex1 {
public:
    int timestamp = 42;
    int get_timestamp() { return timestamp; }
    int get_double_timestamp() { return timestamp * 2; }
};

// 新增auto类型的模板参数Func,用于接收成员函数指针
template<typename T, auto Func>
class Manager {
public:
    void process_data(T& type) {
        // 用成员函数指针的语法调用,等价于你想要的type.FUNC()形式
        int result = (type.*Func)();
        std::cout << "处理结果:" << result << std::endl;
    }
};

int main() {
    Ex1 ex;
    // 实例化时指定要调用的成员函数
    Manager<Ex1, &Ex1::get_timestamp> manager1;
    manager1.process_data(ex); // 输出:处理结果:42

    Manager<Ex1, &Ex1::get_double_timestamp> manager2;
    manager2.process_data(ex); // 输出:处理结果:84

    return 0;
}

方案二:传入自定义可调用对象(包括lambda)

如果你需要传入自定义逻辑(比如lambda),可以借助C++20的std::invocable概念约束可调用对象,统一处理成员函数指针、lambda、函数对象等,虽然不是严格的type.FUNC()语法,但能实现相同逻辑且灵活性更高:

#include <iostream>
#include <concepts>
#include <functional>

class Ex1 {
public:
    int timestamp = 42;
};

// 用std::invocable约束Func必须能接收T&作为参数
template<typename T, typename Func>
requires std::invocable<Func, T&>
class Manager {
private:
    Func func_;

public:
    explicit Manager(Func func) : func_(std::move(func)) {}

    void process_data(T& type) {
        // 用std::invoke统一调用,适配各种可调用类型
        auto result = std::invoke(func_, type);
        std::cout << "处理结果:" << result << std::endl;
    }
};

int main() {
    Ex1 ex;

    // 传入lambda,模拟成员函数逻辑
    Manager<Ex1, decltype([](Ex1& obj) { return obj.timestamp; })> manager1([](Ex1& obj) { return obj.timestamp; });
    manager1.process_data(ex); // 输出:处理结果:42

    // 传入带自定义逻辑的lambda
    Manager<Ex1, decltype([](Ex1& obj) { return obj.timestamp + 10; })> manager2([](Ex1& obj) { return obj.timestamp + 10; });
    manager2.process_data(ex); // 输出:处理结果:52

    // 也可以传入成员函数指针(兼容方案一的场景)
    Manager<Ex1, decltype(&Ex1::timestamp)> manager3(&Ex1::timestamp); // 成员变量指针也能被std::invoke处理
    manager3.process_data(ex); // 输出:处理结果:42

    return 0;
}

注意点

C++是静态类型语言,无法在运行时为类T动态添加成员函数,所以不能让传入的lambda真正成为T的成员函数。但上述两种方案已经可以满足“灵活指定要调用的函数,且逻辑上等价于调用成员函数”的需求。

内容的提问来源于stack exchange,提问作者ATK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:55:41