In my current C++ (14 / 17) project, I need a way to, firstly, find a function and, secondly, invoke the function, if it exists.
At the current stage, I already found a way to tell if the function does exist. But now I am unsure how to actually call or invoke it.
Code
This is my current code for detecting, if the functin (std::string toString()
) does exist:
/**
* Found at:
* https://stackoverflow.com/a/16824239
*/
#include <type_traits>
template<typename, typename T>
struct has_function {
static_assert(std::integral_constant<T, false>::value, "Second template parameter needs to be a function type.");
};
template<typename C, typename Ret, typename... Args>
struct has_function<C, Ret(Args...)> {
private:
template<typename T>
static constexpr auto check(T *) -> typename
std::is_same<decltype(std::declval<T>().toString(std::declval<Args>()...)), Ret>::type;
template<typename>
static constexpr std::false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
My objects and main function to test for the std::string toString()
function:
#include <string>
#include <iostream>
struct Object {
virtual auto toString() -> std::string { return "Object"; }
};
struct TestObject: Object {
std::string toString() override {
return "TestObject";
}
};
struct NonObject { }
int main() {
if (has_function<Object, std::string(void)>::value)
std::cout << "Object has toString()" << std::endl;
if (has_function<TestObject, std::string(void)>::value)
std::cout << "TestObject has toString()" << std::endl;
if (has_function<NonObject, std::string(void)>::value)
std::cout << "NonObject has toString()" << std::endl;
}
Which gives the output:
Object has toString()!
TestObject has toString()!
Now I am asking for a way to actually calling / invoking std::string toString()
.
I did try something like this (within the has_function struct):
static constexpr auto call(...) -> Ret {
return decltype(std::declval<C>().toString(std::declval<Args>() ...))();
}
Which does literally nothing (noticeable?) on Object
as-well-as on TestObject
and does not even compile when used on NonObject
.
(I probably do misunderstand decltype, declval etc.)
Thanks in advance.
Update
This question is not a duplicate.
I am trying to execute / invoke / call the function after it was found.
As I already said: I already have the 'is the function declared?' part working (which I got from https://stackoverflow.com/a/16824239, as seen above).
In the upper section, I explained my try, which obviously did not work out.