导入其他命名空间后,能否在同一作用域恢复默认调用匿名命名空间的message函数?
问题解答
首先修正并展示你的代码:
namespace sally { void message() { std::cout << "Hello from Sally.\n"; } } namespace { void message() { std::cout << "Hello from unnamed.\n"; } } int main() { message(); // 调用匿名命名空间的版本 { message(); // 仍为匿名命名空间版本 using sally::message; message(); // 切换为sally命名空间版本 // 此处能否让message()默认回到匿名版本? } return 0; }
在同一个局部作用域里,一旦用using sally::message;把sally的message引入,没办法直接让message()的默认调用恢复成匿名命名空间的版本——因为这会导致同名冲突,编译器无法判断你要调用哪个message。
不过有两种实用的替代方案:
用嵌套作用域隔离
把需要恢复默认调用的代码放到新的嵌套作用域里,离开引入sally::message的作用域后,message()会自动回到匿名命名空间的版本:int main() { message(); // 匿名版本 { message(); // 匿名版本 using sally::message; message(); // sally版本 } // 离开作用域后自动恢复 message(); // 回到匿名版本 return 0; }给匿名版本起别名
如果必须在同一个作用域内调用匿名版本,可以提前给它定义一个别名,绕开名字冲突:int main() { auto& anon_message = ::message; // 给匿名版本起别名 message(); // 匿名版本 { message(); // 匿名版本 using sally::message; message(); // sally版本 anon_message(); // 直接通过别名调用匿名版本 } return 0; }
要注意:匿名命名空间的成员只有当前翻译单元能访问,::message是全局访问它的唯一方式,但在同一个作用域里同时引入sally::message和::message会触发二义性错误,所以不能用using ::message;来覆盖之前的using声明。
内容的提问来源于stack exchange,提问作者dvk512
相关产品推荐
相关产品推荐

