0
votes

I have a simple template class that has two function pointers and a value. One pointer is a comparison operator and the other is of an object (for instance getX()).

Header:

template<class T>
class A {

public:
    A(T (*function)(), const bool (*op)(T,T),const T value) : 
        function(function), value(value), op(op){}
    bool valid();

private:
    T value;
    T (*function)();
    bool (*op)(T, T);
};

CPP:

#include "A.h"

template<class T>
bool A<T>::valid(){
    return (op(function(),value));
}

So if you created an instance of A:

A<float> a = A<float>(x->getX,operator==,20);

When valid is called is would be equivalent to:

x->getX() == 20;

The actual header/class definitions work fine. The problem is when creating an instance of A; it doesn't work. I figure this is because of the 'x->getX' but is there a way to do what I want?

Thanks.

EDIT::

The exact compiler error is the following:

....\Classes\Objects\B.cpp:42: error: no matching function for call to 'A::A(unresolved overloaded function type, unresolved overloaded function type, float)' ....\Classes\Objects/A.h:30: note: candidates are: A::A(T ()(), const bool ()(T, T), T) [with T = float] ....\Classes\Objects/A.h:26: note: A::A(const A&)

Please note: the 'x->getX' returns a float

1
What does "doesn't work" mean? - Oliver Charlesworth
Function pointers are not functors. A functor is a class that overloads operator(). - Joseph Mansfield
Changed to function pointer. And by 'doesn't work' I mean it doesn't compile when creating an instance of A. - aoi
Paste in the exact compiler error(s). - SirPentor
getX is a method of some class. x is an object of that class. You can't pass x.getX as a pointer to normal function. It doesn't work in C++, like delegates in C#. The easiest way I can think of, to get the result you want is to make a wrapper. There must be some idiomatic way of doing it in C++, but you need someone who knows the language to tell you about it. - Maciej Hehl

1 Answers

0
votes

If you can use C++11:

The way to do what you want is to use std::bind and std::function.

Also, if you want to pass as an argument comparison operators for basic types (int, float ...) you can use the Comparison function objects defined in the <functional> header (std::less, std::greater ...)

#include <functional>
#include <iostream>

template<class T, typename BinaryPredicate>
class A {

public:
    A(std::function<T()> function, BinaryPredicate pred,const T value) : 
        function_(function), pred_(pred), value_(value){}
    bool valid();

private:
    std::function<T()> function_;
    BinaryPredicate    pred_;
    T                  value_;
};

template<class T, typename BinaryPredicate>
bool A<T, BinaryPredicate>::valid(){
    return (pred_(function_(), value_));
}

class X {

   private:
   float val_;

   public:
   X(float val) : val_(val) {}

   float getX() {return val_;}
};

int main(void)
{
   X x(20);

   A<float, std::equal_to<float>> a(std::bind(&X::getX, &x), std::equal_to<float>(), 20);

   std::cout << std::boolalpha << a.valid() << std::endl;

   return (0);
}