bernhard_e
bernhard_e

Reputation: 37

Using a templated function as template parameter

I'm writing a class with a function that is repeatedly called and decided to implement this as giving the function as template parameter. As a concrete example of what I'm talking about, consider the following class:

#include <array>

template<double (*func)(std::array<double,3>)>
class MyClass
{

public:
    MyClass()
    {
        std::array<double,3> v {{0.1,0.2,0.1}};
        func(v);
    }
};

which can then be instantiated with a function, as for example:

double func(std::array<double,3> x)
{
    return x[0]*x[0]+x[1];
}

int main()
{
    MyClass<func> entity;
}

However, I need the function to be callable with different types (the operations in the function are of course applicable to all of them), that is I want to have this function templated, as in:

template<typename scalartype, typename vectype>
scalartype func1(vectype x)
{
    scalartype res = x[0]*x[0]+x[1];
    return res;
}

I can still use this as template parameter, but the function parameter and return type are then fixed in the class. So how can I have the function as templated function available in the class? Such that I can, for example, call it with an std::vector of four integers and have an integer returned.

I tried using template template parameters, but I can't even figure out how to use two template parameters with them (as they only seem to allow the template ... syntax). I'm sorry if this is formulated unclearly, I am still a newcomer.

Upvotes: 0

Views: 127

Answers (1)

super
super

Reputation: 12928

You can put your template function in a class, and then pass in that class to MyClass.

#include <iostream>
#include <vector>
#include <array>

struct templateHolder {
    template <typename vectype, typename scalartype = typename vectype::value_type>
    static scalartype func(vectype x) {
        return x[0] + x[1];
    }
};

template<typename T>
class MyClass
{

public:
    MyClass()
    {
        std::vector<int> vec {1,2};
        std::cout << T::func(vec) << std::endl;

        std::array<double, 2> arr {0.5, 3.33};
        std::cout << T::func(arr) << std::endl;
    }
};

int main() {
    MyClass<templateHolder> foo;
    return 0;
}

I chose to deduce scalartype from vectype. Not necessarily what you want but it could be an option depending on your use-case.

Upvotes: 1

Related Questions