Reputation: 19150
Suppose there's a library, one version of which defines a function with name foo
, and another version has the name changed to foo_other
, but both these functions still have the same arguments and return values. I currently use conditional compilation like this:
#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 corresponding compiler option like -DUSE_NEW_FOO
. I'd rather have the code automatically figure what function it should call, based on it being declared or not in <foo.h>
.
Is there any way to achieve this in any version of C?
If not, will switching to any version of C++ provide me any ways to do this? (assuming the library does all the needed actions like extern "C"
blocks in its headers)? Namely, I'm thinking of somehow making use of SFINAE, but for a global function, rather than method, which was discussed in the linked question.
Upvotes: 6
Views: 285
Reputation: 65770
In C++ you can use expression SFINAE for 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)...);
}
Upvotes: 4
Reputation: 1490
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;
}
Please note I only handle f without any parameters.
Upvotes: 0
Reputation: 8995
If you are statically linking to a function, in most versions of C++, the name of the function is "mangled" to reflect its argument list. Therefore, an attempt to statically link to the library, by a program with an out-of-date .hpp
file, will result in an "unknown symbol" linker-error.
In the C language, there's no metadata of any kind which indicates what the argument list of any exported function actually is.
Realistically, I think, you simply need to be sure that the .h
or .hpp
files that you're using to link to a library, actually reflect the corresponding object-code within whatever version of that library you are using. You also need to be sure that the Makefile
(or "auto-make" process) will correctly identify any-and-all modules within your application which link-to that 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 must see to it that this issue doesn't occur.
Upvotes: 0