0

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?

  • Why not take a `std::function `? – Taekahn Apr 08 '22 at 00:13
  • The issue is you have two different function signatures. One is const bool, the other is bool – Taekahn Apr 08 '22 at 00:14
  • You need to show code that's a minimal version of the code you expect to compile, which means all other errors must be fixed first. For example, your code currently has a mismatch between the names `Class` and `LDI`, and reuses the template parameter name `T` in a nested scope. – Brian Bi Apr 08 '22 at 00:16

3 Answers3

1

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;
}
Wisblade
  • 1,483
  • 4
  • 13
0

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.

jco-iii
  • 16
  • 3
0

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

Jason
  • 36,170
  • 5
  • 26
  • 60