c++ - 粘贴形成了一个无效的处理 token '.'

标签 c++ macros llvm llvm-clang

我正在尝试使用宏来根据类型调用适当的对象。

#define DELEGATE_FUNC(FuncName, kind, paramPtr)         \
    if (kind == 1) {                                    \
        return PolicyObject1.##FuncName(paramPtr);      \
    }                                                   \
    else {                                              \
        return PolicyObject2.##FuncName(paramPtr);      \
    }                                                   \
    return 0;                                           \

(PolicyObject1 和 PolicyObject2 是两个静态对象。) 现在使用宏时,例如

DELEGATE_FUNC(ProcessPreCreate, 1, null_ptr);

它在 VS 2015 中编译良好,但在 LLVM 中给出错误“粘贴形成了一个无效的处理 token ‘.ProcessPreCreate’”

我查找并找到了一些帖子并在一定程度上理解了它——需要双重间接级别,例如 Why do I need double layer of indirection for macros?

但是我无法定义这两层宏,有人可以帮忙吗?

(设计方面的讨论请先搁置)

谢谢

最佳答案

当编译器读取您的 C++ 文件时,第一步就是将它分成标记,例如标识符、字符串文字、数字、标点符号等。C 预处理器处理这些标记,而不是文本## 运算符将标记粘合在一起。因此,例如,如果您有

#define triple(foo) foo##3

然后 triple(x) 将为您提供标识符 x3triple(12) 将为您提供整数 123triple(.) 将为您提供 float .3

但是,您拥有的是 .##FuncName,其中 FuncNameProcessPreCreate。这将创建单个 token .ProcessPreCreate,它不是有效的 C++ token 。如果您直接键入 PolicyObject1.ProcessPreCreate 而不是通过宏,它将被标记为三个标记:PolicyObject1.ProcessPreCreate。这是您的宏需要生成的内容,以便提供有效的 C++ 输出。

要做到这一点,只需去掉 ##。没有必要将 . 粘附到 FuncName 上,因为它们是单独的标记。要检查这一点,您可以在 . 和成员名称之间放置一个空格;它仍然会编译得很好。由于它们是单独的 token ,因此不应也不能将它们粘合在一起。

关于c++ - 粘贴形成了一个无效的处理 token '.',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46356185/

相关文章:

c++ - 为什么要通过右值引用而不是按值来获取 std::initializer_list?

c++ - 在 VS2015 中键入 SFINAE 编译,但生成错误

c++ - 可变参数宏参数计数未按预期工作

attributes - 在源代码上添加一个新属性,该属性会传播到 LLVM 中的 MC 级别?

clang - 有哪些可能的参数可以传递给 Clang 编译器的 -Xclang 选项?

c++ - 为什么 cv::circle() 只显示在特定 RGB 值的 3D 矩阵上?

c++ - g++ 在基类中找不到重载函数

ios - 使用宏检测 iPhone6 和 iPhone6 Plus

macros - 让表格: How to access destructured symbols in a macro?

optimization - clang -O1 和 opt -O1 有什么区别?