user15822443
user15822443

Reputation:

Template function as argument in a class

I wanna pass a function argument in the constructor of the following class:

template <class T>
class Class
{
private:
    bool (*fc)(T, T);
public:
    template <class T>
    Class(const bool(*func)(T, T))
    {

    }
    ~Class() {}
};

bool randomFunction(int a, int b)
{
    return a <= b;
}


int main() {
    LDI<int> test(randomFunction);
    return 0;
}

Severity Code Description Project File Line Suppression State Error C2664 'Class::Class(const bool (__cdecl *)(T,T))': cannot convert argument 1 from 'bool (__cdecl *)(int,int)' to 'const bool (__cdecl *)(T,T)

Error (active) E0289 no instance of constructor "Class::Class[with T=int]" matches the argument list

How do I fix it and where's the problem?

Upvotes: 0

Views: 369

Answers (3)

Alan
Alan

Reputation: 1

There are 2 ways to solve this problem. First is just removing the const from the return type of the parameter func and second is using std::function.

Method 1

Here we remove the const from the return type of the parameter func in the constructor. Also, there is no need for the constructor to be separately templated.

#include <iostream>

template <typename T>
class LDI
{
private:
    bool (*fc)(T, T);
public:
    LDI(bool(*func)(T, T)): fc(func)
    {
       std::cout<<"constructor called"<<std::endl;
    }
    ~LDI() {}
};

bool randomFunction(int a, int b)
{
    std::cout<<"randomFunction called"<<std::endl;
    return a <= b;
}


int main() {
    LDI<int> test(randomFunction);
    return 0;
}

Demo

Method 2

Here we use std::function.

#include <iostream>
#include <functional>
template <typename T>
class LDI
{
private:
    std::function<bool (T, T)> fc; //use std::function
public:
    LDI(std::function<bool (T, T)> func): fc(func)//use std::function in the parameter
    {
       std::cout<<"constructor called"<<std::endl;
    }
    ~LDI() {}
};

bool randomFunction(int a, int b)
{
    std::cout<<"randomFunction called"<<std::endl;
    return a <= b;
}


int main() {
    LDI<int> test(randomFunction);
    return 0;
}

Demo

Upvotes: 0

jco-iii
jco-iii

Reputation: 16

If you're ok with using #include <functional>, here is an example of defining a class that has a function as a variable-style member provided through the constructor. Although I wouldn't recommend the current implementation, geeksforgeeks has a good resource on functions as arguments that can be applied to your constructor.

Upvotes: 0

Wisblade
Wisblade

Reputation: 1644

Remove the template part before the constructor, and use a std::function to simplify your code.

#include <functional>

template <class T> class LDI
{
public:
    // Define this type using std::function, so it can accept function, lambdas, ... very easily.
    // If used with std::bind, can also accept pointers to members functions.
    typedef std::function<bool(T,T)> tmplfunc ;
private:
    tmplfunc fc ;
public:
    // No template here, class is already a template.
    LDI(tmplfunc aFc)
    {
        fc = aFc ;
    }
    ~LDI() {}
};

bool randomFunction(int a, int b)
{
    return a <= b;
}

int main() {
    LDI<int> test(randomFunction);
    LDI<double> test2([](double a, double b) -> bool { return a<=b ;});
    return 0;
}

Upvotes: 1

Related Questions