使用using别名后,前置声明应采用原名还是别名?
C++中using别名后的前置声明:用原名还是别名?
答案很明确:必须使用原名,不能用别名来做前置声明。using关键字定义的别名只是原实体(类型、命名空间等)的“编译期别名”,它们本身不是新的类型或命名空间,前置声明是针对实际存在的实体,而非别名。
咱们结合你给出的示例来拆解:
先看A.h里的定义
using ID = int; namespace AA {class C;} using BB = AA;
错误的写法(写法一)
class ID; // 大错特错!ID是int的别名,不是类,你这里试图声明一个不存在的类ID namespace BB {class C;} // 错误!BB只是AA的别名,不是独立命名空间,前置声明要针对原命名空间AA void f(ID i, BB::C c);
这里的问题在于:
ID只是int的别名,int是内置类型,根本不需要前置声明;就算是自定义类的别名,比如using MyCls = SomeCls,你也不能写class MyCls;,因为MyCls不是新类,只是SomeCls的外号。BB是AA的别名,不是新的命名空间,编译器不知道BB::C对应的实际实体,必须直接针对原命名空间AA来前置声明C。
正确的写法(修正后的写法二)
注意你原来的写法二里class int;是错误的(内置类型不能这么声明),正确的B.h应该是:
// int是内置类型,不需要前置声明 namespace AA {class C;} // 正确:直接前置声明原命名空间AA里的C类 void f(int i, AA::C c); // 如果后续要使用别名,只需在实现文件B.cpp里包含A.h,就能用ID代替int、BB代替AA了
补充说明
如果你的B.h想要直接用ID和BB这些别名,最简单的方式是直接包含A.h,这样就不需要做任何前置声明;但如果因为循环依赖等原因不能包含头文件,那必须用原名来做前置声明,等到实现文件里包含头文件后,再用别名来写代码。
内容的提问来源于stack exchange,提问作者heLomaN
相关产品推荐
相关产品推荐

