Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to pass function in class template without use of auto?

I have following function:

bool comp(Arm l, Arm r) {
    return l.len < r.len;
}

Please, Assume Arm is appropriately declared struct.

I have following class:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

template<typename T, typename F>
class Myclass {
public:
    Arm v[10];
    bool Myfunc(int i) {
        int l = i, r = i + 1;
        return F(v[l], v[s]);
    }
};

When creating object:

Myclass<Arm, decltype(comp)> obj;

I’m getting error: expression list treated as compound expression in functional cast [-fpermissive]

I have tried passing address, I have tried creating function pointer and passing that. I wish to get it worked for C++ 11, Using C++17 I got it worked using:

template<typename T, auto F>
class Myclass {
...

And creating object by:

Myclass<Arm, comp> obj;

And this was working fine.

Example in C++ 11 giving error:

struct Arm {
    int len;
};

template<typename T, typename F>
class Myclass {
public:
    Arm v[10];
    bool Myfunc(int i) {
        int l = i, r = i + 1;
        return F(v[l], v[r]);
    }
};

bool comp(Arm l, Arm r) {
  return l.len < r.len;
}

int main() {
    Myclass<Arm, decltype(comp)> obj;
    obj.Myfunc(2);
    return 0;
}

>Solution :

Prior to C++17 (which can use auto for the template parameter type), it’s usually simplest to create a functor, like a lambda or a struct with an operator() overload:

struct comp {
    bool operator()(Arm l, Arm r) const { return l.len < r.len; }
};

With that, you need to instantiate the functor when needing it (or store an instance in your class):

template<typename T, typename F>
class Myclass {
public:
    // ...
    bool Myfunc(int i) {
        int l = i, r = i + 1;
        return F{}(v[l], v[r]);
//              ^^
//     instantiate the functor
    }
};

And since comp is now a type, you can instantiate your Myclass like so:

Myclass<Arm, comp> obj;

Demo


Without a functor, you could specify the function signature in the template parameter list to make F a function pointer:

struct Arm {
    int len;
};

template <typename T, bool(*F)(T, T)>
//                    ^^^^^^^^^^^^^^
//            the function signature it accepts
class Myclass {
public:
    Arm v[10];
    bool Myfunc(int i) {
        int l = i, r = i + 1;
        return F(v[l], v[r]); // no instantiation needed
    }
};

bool comp(Arm l, Arm r) { return l.len < r.len; }

int main() {
    Myclass<Arm, comp> obj;
    obj.Myfunc(2);
}

Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading