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

能否实现调用不同模板成员函数的for_each_type分发器?

问题解答

原代码无法编译的核心原因是:A::a和A::b是成员函数模板,而for_each_type的模板参数要求的是独立的类模板(template<typename> class Fn),两者类型完全不匹配——成员函数模板不能直接作为模板模板参数传递,也没法像类模板那样用Fn<char>()的方式实例化调用。

我们可以通过调整for_each_type的设计来实现需求,以下是几种可行方案:

方案1:用Lambda包装成员函数调用

修改for_each_type,让它接受一个可调用对象,内部针对每个目标类型调用该对象并传入当前实例:

struct A {
    template<typename T>
    void a() { /* 这里写a<T>的具体逻辑 */ }

    template<typename T>
    void b() { /* 这里写b<T>的具体逻辑 */ }

    template<typename F>
    void for_each_type(F&& func) {
        // 遍历目标类型序列,逐个调用传入的可调用对象
        func.template operator()<char>(*this);
        func.template operator()<int>(*this);
        func.template operator()<float>(*this);
        // 可按需添加更多类型
    }
};

int main() {
    A obj;

    // 调用所有a<T>
    obj.for_each_type([]<typename T>(A& self) {
        self.template a<T>();
    });

    // 调用所有b<T>同理
    obj.for_each_type([]<typename T>(A& self) {
        self.template b<T>();
    });
}

方案2:用函数对象类封装成员函数

如果需要复用调用逻辑,可以定义专门的函数对象类,通过模板参数指定要调用的成员函数:

struct A {
    template<typename T>
    void a() { /* 实现 */ }

    template<typename T>
    void b() { /* 实现 */ }

    // 调整for_each_type,接受模板化的函数对象
    template<template<typename> class FuncObj>
    void for_each_type() {
        FuncObj<char>{}(*this);
        FuncObj<int>{}(*this);
        FuncObj<float>{}(*this);
    }
};

// 封装调用a<T>的函数对象
template<typename T>
struct CallA {
    void operator()(A& obj) {
        obj.template a<T>();
    }
};

// 封装调用b<T>的函数对象
template<typename T>
struct CallB {
    void operator()(A& obj) {
        obj.template b<T>();
    }
};

int main() {
    A obj;

    // 一次性调用所有a<T>
    obj.for_each_type<CallA>();
    // 一次性调用所有b<T>
    obj.for_each_type<CallB>();
}

方案3:C++20+用概念简化(可选)

如果使用C++20及以上版本,可以用概念约束可调用对象,让代码更简洁清晰:

#include <concepts>

struct A {
    template<typename T>
    void a() {}

    template<typename T>
    void b() {}

    template<std::invocable<A&, char> F>
    requires std::invocable<A&, int> && std::invocable<A&, float>
    void for_each_type(F&& func) {
        // 用类型标签传递目标类型
        func(*this, char{});
        func(*this, int{});
        func(*this, float{});
    }
};

int main() {
    A obj;
    obj.for_each_type([](A& self, auto tag) {
        using T = decltype(tag);
        self.template a<T>();
    });
}

核心思路总结:成员函数模板不能直接作为模板模板参数传递,必须通过Lambda、函数对象等可调用载体,把成员函数的调用逻辑包装起来,让for_each_type能遍历目标类型序列,逐个触发对应成员函数的调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:12:23