Is there a way to check if a function has been declared?

Suppose there is a library, one of which defines a function named foo , and the other version has a name changed to foo_other , but both of these functions still have the same arguments and return values. I am currently using conditional compilation as follows:

 #include <foo.h> #ifdef USE_NEW_FOO #define trueFoo foo_other #else #define trueFoo foo #endif 

But this requires some external detection of the library version and setting the appropriate compiler option, for example -DUSE_NEW_FOO . I would prefer the code to automatically determine which function it should call based on the declaration or not in <foo.h> .

Is there a way to achieve this in any version of C?

If not, will any way to do this switch to any version of C ++? (assuming the library performs all the necessary actions, such as extern "C" blocks in its headers)? Namely, I’m thinking about somehow using SFINAE , but for the global function, not the method that was discussed in the related question.

+6
source share
3 answers

In C ++, you can use the SFINAE expression to do this:

 //this template only enabled if foo is declared with the right args template <typename... Args> auto trueFoo (Args&&... args) -> decltype(foo(std::forward<Args>(args)...)) { return foo(std::forward<Args>(args)...); } //ditto for fooOther template <typename... Args> auto trueFoo (Args&&... args) -> decltype(fooOther(std::forward<Args>(args)...)) { return fooOther(std::forward<Args>(args)...); } 
+4
source

If you statically refer to a function, in most versions of C ++ the function name is "malformed" to reflect the list of arguments. Therefore, trying to statically link to a library using a program with an obsolete .hpp file will result in an "unknown character" linker error.

In C, there is no metadata of any type that indicates that there is actually a list of arguments to any exported function.

Actually, I think you just need to be sure that the .h or .hpp files that you use to link to the library actually reflect the corresponding object code in any version of the library that you are using. You must also be sure that the Makefile process (or β€œauto-make”) will correctly identify all of all the modules in your application that reference this library and which therefore must be recompiled in case of any changes to It. (If it were me, I would recompile the entire application.) In short, you should ensure that this problem does not occur.

0
source

In C ++, you can do something like this:

 #include <iostream> #include <type_traits> //#define DEFINE_F #ifdef DEFINE_F void f() { } #endif namespace { constexpr struct special { std::false_type operator()() const; }f; } struct checkForF { static const constexpr auto value = std::conditional< std::is_same<std::false_type, decltype(::f())>::value, std::false_type, std::true_type >::type(); }; int main() { std::cout << checkForF::value << std::endl; } 

ideone

Please note that I am processing f without any parameters.

0
source

Source: https://habr.com/ru/post/988512/


All Articles