I have some C++ code that is automatically generated to wrap some C code.
The C code has a predictable structure with the exception that it has/has not a certain function.
Since the C++ code is derived from a description that does not have this information. I would like to use the template processor to decide if this function can be called.
small example:
struct SomeStruct{
int indicatorMember;
};
extern "C" void someFun(struct SomeStruct* somePointer){
}
void someCPPcode(){
SomeStruct s;
// do something
someMechanismToCall_someFunIfExists(&s);
// do something other
}
How does someMechanismToCall_someFunIfExists
have to look like, so that someCPPcode can be compiled/run in cases there someFun
does exist and if it does not exist?
Is this even possible?
It would also be possible to decide if this function exists, if a certain member is part of a structure.
so, if indicatorMember
does exist, the function also exists.
You might use overload with lower priority to solve your issue:
// "C-Header"
struct SomeStruct
{
int indicatorMember;
};
// Present or not
extern "C" void someFun(struct SomeStruct* somePointer){
}
// Fallback
void someFun(...) { /*Empty*/ }
void someCPPcode()
{
SomeStruct s;
// do something
someFun(&s);
// do something other
}
it would also be possible to decide if this function exists, if a certain member is part of a structure. so, if
indicatorMember
does exist, the function also exists.
There are several ways to detect presence of member, such as use of std::experimental::is_detected
.
but outside template, you still have issue:
decltype(auto) someFunIfExists([[maybe_unused]] SomeStruct* p)
{
if constexpr (has_someFunc<SomeStruct>::value) {
return someFun(p); // Not discarded as you might expect -> Error
}
}
as if constexpr (false) { static_assert(false); }
is invalid).
So you have to wrap the function inside template:
template <typename T>
decltype(auto) someFunIfExists([[maybe_unused]] T* p)
{
if constexpr (has_someFunc<T>::value) {
return someFun(p);
}
}
void someCPPcode(){
SomeStruct s;
// do something
someFunIfExists(&s);
// do something other
}