想象一下,我有两个.hpp
个文件:
#ifndef _DEF_FILE_1_
#define _DEF_FILE_1_
inline void some_function_1(){
/*do stuff*/
}
#endif
和
#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#ifdef _DEF_FILE_1_
inline void some_function_2(){
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2(){
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
当我不知道文件的顺序包括在内时,我的问题就出现了,例如:
在main.cpp
我可以有类似的东西:
#include "file1.hpp"
#include "file2.hpp"
int main(){
some_function_2();
/*will call the function that uses some_function_1()*/
}
或
#include "file2.hpp"
#include "file1.hpp"
int main(){
some_function_2();
/*will call the function that doesn't use some_function_1()*/
}
有没有办法确保file1.hpp
和file2.hpp
包含在内,然后some_function_2()
会调用some_function_1()
?
PS:一种解决方案是在file1.hpp
中加入file2.hpp
,但我做不到
因为我开发的代码可能依赖于某些库,也可能不依赖于某些库
最终用户可能有也可能没有。
PPS:我能想到的唯一其他解决方案(即使我不知道如何解决)
实现这一点)将“删除”some_method_2()
的定义
包含file1.hpp
,然后重新加入file2.hpp
。
答案 0 :(得分:1)
我认为正确的解决方案是使用SFINAE机制和模板而不是预处理器技巧重写some_function_2()
。那样的实例化将在cpp文件中发生,在那里可以知道some_function_1()
是否存在并且include的顺序无关紧要。
答案 1 :(得分:0)
您的用户应该知道他们是否有“某个库”,或者您应该有一些方法来确定该库是否存在。所以你可以这样做:
在file2.hpp
中#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#ifdef _DEF_HAS_SOME_LIBRARY_
#include "file1.hpp"
inline void some_function_2(){
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2(){
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
或者,如果可能的话,完全消除file1.hpp,并将some_function_1()
放在上面#include "file1.hpp"
的位置。
现在main.cpp应该只包含file2.hpp。
// optionally #define _DEF_HAS_SOME_LIBRARY_
#include "file2.hpp"
int main(){
some_function_2();
/*will call the function that uses some_function_1()*/
}
但是,在我看来,避免预处理器的解决方案会更好。
答案 2 :(得分:0)
如果你不知道文件是否存在并且需要处理它,那么c和c ++预处理器都不会处理文件存在检查。这是配置工具背后的原因之一。
您需要事先探测此信息,并在编译之前进行设置。有很多方法可以做到这一点。通常使用工具/脚本创建一些带有适当定义的configure.h
标头。例如。包含这样的行#define FILE1_HPP_EXISTS 1
。
然后,您始终可以依赖configure.h
的存在,它将提供您需要的信息。
答案 3 :(得分:0)
如果您的编译器允许,您可以使用_has_include
宏:
只需将file2.hpp
更改为:
#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#if defined(__has_include) && __has_include("file1.hpp")
# include "file1.hpp"
inline void some_function_2() {
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2() {
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
但请记住,这是一个特定于编译器的扩展。