问题
Imagine I have two .hpp
files:
#ifndef _DEF_FILE_1_
#define _DEF_FILE_1_
inline void some_function_1(){
/*do stuff*/
}
#endif
and
#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
My problem arises when I don't know in which order the files are included, e.g:
in the main.cpp
i can have something like :
#include "file1.hpp"
#include "file2.hpp"
int main(){
some_function_2();
/*will call the function that uses some_function_1()*/
}
or
#include "file2.hpp"
#include "file1.hpp"
int main(){
some_function_2();
/*will call the function that doesn't use some_function_1()*/
}
Is there a way to make sure that as soon as both file1.hpp
and file2.hpp
are included, then some_function_2()
will call some_function_1()
?
PS: One solution would be to include file1.hpp
in file2.hpp
but I can't do
that because I developp a code that may or may not depend on some library
that the end-user may or may not have.
PPS: The only other solution I can think of (even if I don't know how to
achieve this) would be to "delete" the definition of some_method_2()
when
file1.hpp
is included and then reinclude file2.hpp
.
回答1:
I believe proper solution would be to rewrite some_function_2()
using SFINAE mechanism and template instead of preprocessor tricks. That way instantiation will happen in cpp file where it would be known if some_function_1()
exists and order of include will not matter.
回答2:
Your users should know if they have "some library" or, you should have some way of determining if that library is present. So you could do something like:
In 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
Or if possible eliminate file1.hpp entirely, and put some_function_1()
in the location of #include "file1.hpp"
above.
Now main.cpp should only include 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()*/
}
though, a solution that avoids the preprocessor would be better in my opinion.
回答3:
If you don't know whether the file exists and need to handle that, well, neither c nor c++ preprocessor handle file existence checks. This is one of the reasons behind configure tools.
You need to probe for this information beforehand, and set it before compiling. There many ways to do it. Usually a tool / script, creates some configure.h
header with appropriate defines is created. E.g. containing such line #define FILE1_HPP_EXISTS 1
.
Then you can always rely on presence of configure.h
and it will provide information you need.
回答4:
If your compiler allows it you might use the _has_include
macro:
Just change you file2.hpp
to:
#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
But keep in mind that this is a compiler specific extension.
来源:https://stackoverflow.com/questions/32631513/force-one-include-file-to-be-included-before-another