2011-01-20 67 views
18

我试图在宏中生成包含文件名。这应该是在C++中的法律:在宏中生成包含文件名

#define INCLUDE_FILE "module_impl_win.hpp" 
#include INCLUDE_FILE 

这工作正常,但只要我尝试生成的文件名是failes编译

#define INCLUDE_FILE(M) M##"_impl_win.hpp" 
#include INCLUDE_FILE("module") 

其实它给我的警告上MSVC2010

警告C4067:意外的标记以下预处理器指令 - 预计一纽林

但它不包含该文件。

什么问题?我怎样才能摆脱它?

回答

18

我会这样做使用助手引用宏。像这样的东西会给你想要的东西:

#define QUOTEME(M)  #M 
#define INCLUDE_FILE(M) QUOTEME(M##_impl_win.hpp) 

#include INCLUDE_FILE(module) 
3

的问题是,最终你的代码应该是这样的:

#include "module""_impl_win.hpp" 

这会产生同样的警告和错误您所看到,但在一个稍微更明显的方式。

虽然编译器会接受该语法,但预处理器不会。

我没有建议让你正在尝试做的工作。个人不希望使用这种类型的宏,因为它使得更难以直观地浏览代码,并且可能会阻止很多编辑快速浏览代码。

+0

谢谢,不知道它连接这样的字符串。想象一下,有数百个文件包含#ifdef ... #endif平台特定的头文件。如果明天我会添加对另一个平台的支持,那么我需要编辑所有这些文件,而不是只编辑一个宏并添加平台特定的实现文件。这很伤心。 – ledokol 2011-01-20 06:29:45

+0

@ledokol:为什么特定于平台的功能不能被拆分为单独的头文件和源文件,这些文件不包含在其他地方?应该很容易将平台特定的和依赖于平台的功能整合到相对较小的一组文件中。 – 2011-01-20 06:43:30

3

您还可以使用升压预处理器,尤其是BOOST_PP_STRINGIZE/BOOST_PP_CAT宏:

#include <boost/preprocessor/cat.hpp> 
#include <boost/preprocessor/stringize.hpp> 

#define INCLUDE_FILE(M) BOOST_PP_STRINGIZE(BOOST_PP_CAT(M, _impl_win.hpp)) 

// expands to: #include "module_impl_win.hpp" 
#include INCLUDE_FILE(module) 

(参见C Macro - DynamiC#include

注意,这患有与@ Andrew的答案相同的问题(导致下划线=保留的标识符)。