c++ - 为什么这个宏没有得到扩展?
问题描述
这是预处理器的输出assets.cpp.i
:
#define CLASSNAME GAMEOBJECT
#define CLASSNAME_NORMAL GameObject
#define GAMEOBJECT_EXPANSION(FUNC) FUNC(std::vector<std::shared_ptr<Component>>, comps)
# 1 "/home/rubend/p/engine/libs/include/prefab.h" 1
#define prefab_h
#define PREFAB_VAR_ENUM_NAME(name) name ##_enum
#define PREFAB_VAR_ENUM_DIRTY(type,name) PREFAB_VAR_ENUM_NAME(name),
# 42 "/home/rubend/p/engine/libs/include/prefab.h"
#define _CLASSNAME_EXPANSION(classname,func) classname ## _EXPANSION(func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
template<class T>
class Prefab:public File{
private:
std::shared_ptr<T> ref;
protected:
enum DIRTY_ENUM{First, CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY) Last};
};
现在为什么根本CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
不扩大?
连接标记##我不知道有什么特别之处吗?
我正在使用 GCC 9.3 和 CMake 3.16.5
回答
通过添加另一个宏来修复它:
#define __CLASSNAME_EXPANSION(classname, func) classname ## _EXPANSION(func)
#define _CLASSNAME_EXPANSION(classname, func) __CLASSNAME_EXPANSION(classname,func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
20 年 12 月 4 日更新
@rici 指出我应该把下划线放在最后,因为内部库宏在一开始就使用它们。
解决方案
如果您跟随扩展,您会注意到 CLASSNAME_EXPANSION 正在扩展 - 到它自己。
让我们一步一步来看看会发生什么:
CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> _CLASSNAME_EXPANSION(CLASSNAME,PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME ## _EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
由于这个宏的名字和原来的名字一样(即它是一个嵌套的名字),我们不展开它。
推荐阅读
- sql - 在 SQL 查询中将 nonth 从 8 更改为 08
- javascript - 在 javascript 中合并并创建一个唯一区分大小写的数组
- javascript - window.print() 函数如何处理像素和百分比 CSS 应用程序
- azure-devops - 自动化多仓库 CD 管道中的部署前审批
- c# - 如何在 Flipview 控制器中插入 WebBrowser
- java - 为什么我在 Matrix 中填写 Integer.MAX_VALUE
- react-native - 如何在不弹出的情况下安装反应本机相机
- python - Matplotlib 饼图/圆环图注释文本大小
- sql - 如何在 Laravel 中的其他 2 个连接表上按日期列排序表?
- json - 如何在日志查询中传递arm模板的参数或变量