Pointer to a variable static function template. How?

I have a code:

class Factory
{
public:
    template<typename ...Args>
    static void testFunc(Args&& ...args)
    {
        cout << "inside function";
    }
};

Is it possible to create a pointer to testFunc ? All I can do is define it like this:

// main
void(*pFunc)() = &Factory::testFunc;
pFunc();

This works, but I cannot pass a variable number of arguments, for example:

void(*pFunc)(WHAT_TO_TYPE_HERE?) = &Factory::testFunc;
pFunc(10, false, 'a', 11.5);

PS: with ellipsis (...) everything works.

+4
source share
5 answers

Is it possible to create a pointer to testFunc?

testFunc , Args. . , , testFunc, testFunc<int, double> testFunc<>.

, , 0- testFunc

void(*pFunc)() = &Factory::testFunc;

void(*pFunc)() = &Factory::testFunc<>;

Factory::testFunc <> - , .

+3

:

void(*pFunc)(WHAT_TO_TYPE_HERE?) = &Factory::testFunc;
pFunc(10, false, 'a', 11.5);

:

void (*pFunc)(int&&, bool&&, char&&, double&&) = 
    &Factory::testFunc<int, bool, char, double>;

testFunc , . , .

+1

. :

  • (testFunc - ( ), ( , <> does; , )
  • , (, && )

:

#include <iostream>

// Ignore this printHelper stuff; it just prints out the arguments
static void printHelper()
{
}

template <typename T>
static void printHelper(T&& arg)
{
    std::cout << arg;
}

template<typename T, typename ...Args>
static void printHelper(T&& arg, Args&& ...args)
{
    std::cout << arg << ", ";
    printHelper(args...);
}

class Factory
{
public:
    template<typename ...Args>
    static void testFunc(Args&& ...args)
    {
        std::cout << "inside function; args are: ";
        printHelper(args...);
        std::cout << std::endl;
    }
};

int main()
{
    void (*pFunc1)() = &Factory::testFunc<>;
    pFunc1();

    void (*pFunc2)(int&&, char&&, double&&) = &Factory::testFunc<int, char, double>;
    pFunc2(1, 'a', 3.14);
}
+1

, :

void(*pFunc)(WHAT_TO_TYPE_HERE?) = &Factory::testFunc;
pFunc(10, false, 'a', 11.5);

WHAT_TO_TYPE_HERE

void(*pFunc)(int&&, bool&&, char&&, double&&) = &Factory::testFunc;
pFunc(10, false, 'a', 11.5);

, rvalue/lvalue , .

, :

template<class Sig, class Function>
struct testfunc_as_function_ptr;
template<class R, class...Args>
struct testfunc_as_function_ptr {
  R(*)(Args...) operator()() const {
    return [](Args...args){ return Factory::testFunc(std::forward<Args>(args)...); };
  }
};

, :

void(*pFunc)(int,bool,char,double) = testfunc_as_function_ptr<void(int, bool, char, double)>{}();

, testFunc, .

, , ENTIRE template, :

.

, , , "" ++. . template - - .

. .

, template<class...Args> void testFunc(Args&& ...args) . , - , , . "" .

, , , (, , , , - , ).

( ) , "" ( ). .

void testFunc(...) . , . , void testFunc(...).

, , (), . , , , , , .

, , , .

++ . (), .

, , Args.... , , , Arg ?

, :

struct printable { virtual std::string to_string() const = 0; ~printable(); };

using printer = void(*)(std::vector<std::unique_ptr<printable>>);

printer - , vector printable. , T printable.

, , , Args....

, , - boost::any, , . void (*)(...) C-style variardic, -, , .

+1

, &Factory::testFunc , .

( ) , , , .

Just static_castto have a pointer to a function of the desired type (or use it in another context, making the type obvious), for example:

void(*pFunc)() = &Factory::testFunc;
f( (void(*)())&Factory::testFunc); // static_cast to get the right overload

Look at coliru: http://coliru.stacked-crooked.com/a/13571ddf095df15f

Of course, since this is a template function, you can select one of the functions from the overload set by explicitly specifying arguments, for example:

void(*pFunc)() = &Factory::testFunc<>;
+1
source

All Articles