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

C++中能否重载模板类?如何实现类似C# Action的多模板版本

在C++中实现类似C# Action类的方案

首先明确:C++不允许直接重载类——不管是普通类与模板类同名,还是不同模板参数数量的模板类同名,同一作用域下类名必须唯一,这就是你之前代码编译报错的原因。

下面提供两种可行的替代方案:

方案1:自定义模板特化实现

通过可变参数主模板+特化的方式,实现不同参数数量的Action版本:

// 可变参数主模板(仅作为基础框架,不直接实例化)
template<typename... Args>
class Action;

// 无参数的Action特化版本
template<>
class Action<>
{
public:
    using FuncType = void(*)();
    Action(FuncType func) : m_func(func) {}
    void Invoke() { m_func(); }
private:
    FuncType m_func;
};

// 单参数的Action特化版本
template<typename T1>
class Action<T1>
{
public:
    using FuncType = void(*)(T1);
    Action(FuncType func) : m_func(func) {}
    void Invoke(T1 arg) { m_func(arg); }
private:
    FuncType m_func;
};

// 双参数的Action特化版本
template<typename T1, typename T2>
class Action<T1, T2>
{
public:
    using FuncType = void(*)(T1, T2);
    Action(FuncType func) : m_func(func) {}
    void Invoke(T1 arg1, T2 arg2) { m_func(arg1, arg2); }
private:
    FuncType m_func;
};

使用示例完全符合你的预期:

void func0() { /* 无参函数实现 */ }
void func1(int a) { /* 单参函数实现 */ }
void func2(int a, float b) { /* 双参函数实现 */ }

int main()
{
    Action<> a1(func0);
    Action<int> a2(func1);
    Action<int, float> a3(func2);

    a1.Invoke();
    a2.Invoke(10);
    a3.Invoke(10, 3.14f);

    return 0;
}

方案2:直接复用std::function(推荐)

C++标准库中的std::function<void(Args...)>完全具备C# Action的功能,还支持lambda、成员函数、捕获表达式等更多场景,无需重复造轮子:

#include <functional>

void func0() { /* 实现 */ }
void func1(int a) { /* 实现 */ }

int main()
{
    // 对应Action<>
    std::function<void()> a1 = func0;
    // 对应Action<int>
    std::function<void(int)> a2 = func1;
    // 对应Action<int, float>
    std::function<void(int, float)> a3 = [](int x, float y) { /* lambda实现 */ };

    a1();
    a2(5);
    a3(5, 2.5f);

    return 0;
}

如果想要完全贴合C#的命名习惯,可以用using做一层别名封装:

#include <functional>

template<typename... Args>
using Action = std::function<void(Args...)>;

// 使用方式和C#一致
int main()
{
    Action<> a1 = [](){ /* ... */ };
    Action<int> a2 = [](int x){ /* ... */ };
    Action<int, float> a3 = [](int x, float y){ /* ... */ };

    a1();
    a2(5);
    a3(5, 2.5f);

    return 0;
}

关于你之前错误写法的说明

  • 第一种写法直接重复定义Action类,违反了C++同一作用域类名唯一的规则,必然编译报错。
  • 第二种写法存在语法错误:模板参数声明缺少typename关键字,特化的写法Action<T1.>也是无效的,不符合C++模板特化的语法规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:51:56