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

C++中派生类调用基类同名非虚函数为何需用using关键字?

问题:派生类无法调用基类重载的operator()的原因

原始代码

#include <iostream>
#include <string>
class Base {
public:
    void operator()(std::string str) {
        std::cout << "base str: " << str << std::endl;
    }

    virtual void operator()(double d) {
        std::cout << "base double: "<< d << std::endl;
    }

};

class Derived: public Base {
public:
    void operator()(double d) override {
        std::cout << "derived double: "<< d << std::endl;
    }
};

int main() {
    Derived derived;
    derived(8.0);
    derived(std::string("hi"));
}

编译错误

编译时会报错:no match for call to ‘(Derived) (std::string)’

修改后的可行代码

class Derived: public Base {
public:
    using Base::operator();
    void operator()(double d) override {
        std::cout << "derived double: "<< d << std::endl;
    }
};

原因解释

这是C++的**名称隐藏(name hiding)**规则导致的:

  • 当派生类中定义了与基类同名的函数(这里是operator()),无论参数列表是否一致,基类中所有同名的重载函数都会被派生类的同名函数隐藏,无法直接通过派生类对象调用。
  • 派生类里的void operator()(double d)和基类的operator()属于同名函数,因此基类中接收std::string参数的operator()版本被隐藏。编译器处理derived(std::string("hi"))时,只会在派生类作用域内查找operator(),找不到匹配的版本就会报错。
  • 添加using Base::operator();的作用是将基类中所有名为operator()的函数引入到派生类的作用域中,这样编译器就能找到基类的std::string版本重载,代码即可正常编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:56:54