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

如何在C++中获取函数调用者的类型?

在C++中获取函数调用者类型的可行方案

嘿,我太懂这种“明明被说不推荐但确实适配自己场景”的感受了——虽然关于这个问题的讨论已经不少,给新手的建议大多是直接喊**“别这么做,这属于不良编程习惯”**,但如果这个方案刚好契合你的需求,那它就是合适的选择。

你的核心需求是:在C++中获取函数调用者的类型,用于typeid(CALLER)操作,结合你提到的场景——有一个AnalyzedObject作为多个多态Evaluator的评估对象,我来给你几个针对性的可行思路:

方案一:模板推导+调用者传递自身类型(最安全推荐)

这是符合C++标准、无未定义行为的最优解,只需要调用者稍微配合传递一下自身指针:

#include <typeinfo>
#include <iostream>

class AnalyzedObject {
public:
    // 模板方法,自动推导调用者类型
    template<typename CallerType>
    void processEvaluation(CallerType* caller) {
        // 直接通过typeid获取调用者的实际类型
        const std::type_info& callerType = typeid(CallerType);
        std::cout << "当前调用者类型:" << callerType.name() << std::endl;

        // 结合你的场景,比如判断调用者是否为特定Evaluator子类
        if (callerType == typeid(SpecificEvaluator)) {
            // 针对SpecificEvaluator的专属逻辑
            std::cout << "处理SpecificEvaluator的评估请求" << std::endl;
        } else if (callerType == typeid(AnotherEvaluator)) {
            // 其他Evaluator的逻辑
            std::cout << "处理AnotherEvaluator的评估请求" << std::endl;
        }
    }
};

// 多态Evaluator基类
class BaseEvaluator {
public:
    virtual void evaluate(AnalyzedObject& obj) = 0;
    virtual ~BaseEvaluator() = default;
};

// 具体Evaluator子类
class SpecificEvaluator : public BaseEvaluator {
public:
    void evaluate(AnalyzedObject& obj) override {
        // 传递this指针,模板自动推导当前类型
        obj.processEvaluation(this);
    }
};

class AnotherEvaluator : public BaseEvaluator {
public:
    void evaluate(AnalyzedObject& obj) override {
        obj.processEvaluation(this);
    }
};

// 测试代码
int main() {
    AnalyzedObject obj;
    SpecificEvaluator eval1;
    AnotherEvaluator eval2;

    eval1.evaluate(obj);
    eval2.evaluate(obj);
    return 0;
}

这个方案的优势在于:

  • 完全符合标准,跨编译器兼容
  • 哪怕通过基类指针调用(比如BaseEvaluator* ptr = new SpecificEvaluator();),传递this依然能准确获取实际子类的类型
  • 代码可读性高,耦合度可控(如果后续新增Evaluator,只需要在processEvaluation里新增判断逻辑即可)

方案二:宏辅助传递类型(应急/简化调用)

如果你想让调用者的代码更简洁,可以用宏来封装类型传递的逻辑,本质和方案一类似,但减少了模板代码的显性书写:

#include <typeinfo>
#include <iostream>

class AnalyzedObject {
public:
    void processEvaluation(const std::type_info& callerType) {
        std::cout << "当前调用者类型:" << callerType.name() << std::endl;
        // 同样的类型判断逻辑
        if (callerType == typeid(SpecificEvaluator)) {
            std::cout << "处理SpecificEvaluator的评估请求" << std::endl;
        }
    }
};

// 定义宏,自动获取调用者类型并传递
#define EVALUATE(obj) obj.processEvaluation(typeid(*this))

// Evaluator类定义同方案一
class SpecificEvaluator : public BaseEvaluator {
public:
    void evaluate(AnalyzedObject& obj) override {
        // 直接调用宏即可
        EVALUATE(obj);
    }
};

不过这个方案要注意:宏的可读性稍差,而且如果在非成员函数中调用会报错(因为this不存在),所以只适合你的类成员函数调用场景。

为什么大家说这是不良编程习惯?

最后也解释一下为啥很多开发者不推荐这种做法:它会让AnalyzedObject和调用它的Evaluator类型产生耦合,违反了依赖倒置原则——原本AnalyzedObject应该只关心自己的逻辑,现在却要依赖调用者的类型。如果后续Evaluator的子类频繁新增或修改,AnalyzedObject的逻辑也需要跟着改动,维护成本会变高。

但如果你的场景中,Evaluator的类型是相对稳定的,或者这种类型判断是业务逻辑的核心需求,那这个方案完全是合理的,不用被“不良习惯”的说法束缚。

内容的提问来源于stack exchange,提问作者Szał Pał

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:56:16