1

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.

Sakul6499
  • 29
  • 1
  • 7
  • 1
    Template to detect if a method exists : https://stackoverflow.com/questions/257288/is-it-possible-to-write-a-template-to-check-for-a-functions-existence – François Andrieux Jun 08 '17 at 13:43
  • 2
    There are so many questions on here for this topic. Just search. – Barry Jun 08 '17 at 13:47
  • `toString` appears to be a non-static member function. On what object do you want to call it? – Angew is no longer proud of SO Jun 08 '17 at 13:59
  • Please read the full question. I already did found a solution to check if a function does exist (also linked to another post). My problem is that I can't invoke / execute / call this function or do not know exactly how to use it, as I found it. – Sakul6499 Jun 08 '17 at 15:32

0 Answers0