关于《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
相关产品推荐
相关产品推荐

