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

关于《C++ Primer》同名实体隐藏规则的实验验证与疑问

关于《C++ Primer》“同名外部作用域实体被隐藏”表述的验证与答疑

嘿,咱们来理清楚你遇到的这个问题:你看到《C++ Primer》第五版18.2.2节里的这句话:

Entities with the same name defined in an outer scope are hidden

然后做了实验,但结果和预期不符——其实这句话的表述是准确的,只是你的实验场景没对应上它描述的规则~

你的实验为什么没触发“隐藏”规则?

你代码里的using std::abs是把标准库的abs函数引入到test函数的作用域,这不属于“内部作用域定义同名实体”的场景。对于函数来说,using声明的作用是把外部命名空间的函数加入当前作用域的重载集合,和你在全局作用域自定义的abs(int)形成重载关系。

至于你实际调用到了自定义版本,大概率是因为你自定义的abs和std::abs(int)签名完全一致,部分编译器在这种重载决议中会优先匹配全局作用域的自定义函数(或者头文件包含的细节导致std::abs(int)没被正确引入重载集合),但这本质上和“隐藏”规则无关。

正确的验证代码

要验证书中的表述,你需要在内部作用域直接定义同名实体,这样外部作用域的同名实体才会被隐藏。比如这段代码:

#include <iostream>

// 全局作用域的abs函数
int abs(int n) { 
    std::cout << "全局作用域的abs" << std::endl; 
    return 0; 
}

void test() {
    // 在test函数内部定义同名函数,此时全局的abs会被隐藏
    int abs(int n) {
        std::cout << "test函数内的abs" << std::endl;
        return 1;
    }
    // 这里调用的是test内部的abs,全局版本已经被隐藏
    std::cout << abs(7) << std::endl; 
}

int main() { 
    test(); 
    return 0; 
}

运行这段代码会输出:

test函数内的abs
1

完美符合书中“外部作用域的同名实体被隐藏”的描述。

额外补充:using声明的特殊规则

顺便说下using声明的特殊情况,避免混淆:

  • 对于非函数实体(比如变量):如果内部作用域通过using引入一个名字,同时外部有同名实体,外部的会被隐藏。比如:
    int x = 10;
    void test() {
        int x = 20; // 内部定义同名变量,全局x被隐藏
        std::cout << x << std::endl; // 输出20
    }
    
  • 对于函数实体:using声明引入的函数会和当前、外部作用域的同名函数构成重载集合,不会直接触发隐藏——除非内部作用域定义了同签名的函数,这时候会直接覆盖(而非隐藏)外部的版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:12:46