mardi 24 janvier 2017

Passing (partially) templated template function as std::function(or function pointer)

#include <vector>
#include <functional>

template<class F>
class Foo
{
public:
    template <class T>
    void std_function(std::function<F(std::vector<T>)> functor)
    {
        /* something */
    }

    template <class T>
    void func_ptr(F (*funtor)(std::vector<T>))
    {
        /* something else */
    }
};

template<class T, class F>
F bar(std::vector<T>)
{
    return F();
}

int main()
{
    Foo<double> test;
    std::function<double(std::vector<int>)> barz = bar<int, double>;

    test.std_function(bar<int, double>); //error 1
    test.std_function(barz); //OK 1
    test.func_ptr(bar<int, double>); //OK 2

    test.std_function(bar<int>); //error 2::1
    test.func_ptr(bar<int>); //error 2::2

    return 0;
}

Question 1.

Line error 1 : I am trying to pass explicitly instantiated template function(bar<int, double>) as std::function, but It is not legal.

Line OK 1 : If I wrap bar<int, double> into std::function<double(std::vector<int>)> and pass wrapped functor, it is legal now.

Line OK 2 : If I pass bar<int, double> through Foo::func_ptr, which gets function pointer as argument instead of std::function, it is also legal.

I want to make the Line error 1 legal. As in the Line OK 2, it is possible to pass bar<int, double> without any wrapper(unlike Line OK 1) and keep same form. But, the parameter type is different. I want to pass as std::function, not function pointer.

Question 2.

Line error 2::1 and 2::2 : What I am trying to achieve here is, I want class Foo to deduce return type of bar as its class template type F(for the code above, F is double). So I can just pass as bar<int>, not bar<int, double>.

But It seems to fail deduction, because even if I pass bar<int> through Foo::func_ptr, it still produces error. How can I make this code work as my intention?

Aucun commentaire:

Enregistrer un commentaire