Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a function pointer to a built-in arithmetic operator? [duplicate]

Tags:

c++

operators

I want to refer to function pointers of built-in operators, but I don't know how to specify the specific type overloads.

I have the following template class signature:

template<typename ParamsType, typename FnCompareType>
class MyAction
{
public:
    MyAction(ParamsType& arg0, ParamsType& arg1, FnCompareType& fnCpmpare) 
    : arg0_(arg0), arg1_(arg1), fnCompare_(fnCpmpare) {}

    bool operator()()
    {
        if((*fnCompare_)(arg0_,arg1_)
        {
            // do this
        }
        else
        {
            // do s.th. else
        }
    }

private:
    ParamsType& arg0_;
    ParamsType& arg1_;
    FnCompareType& fnCompare_;
}

And want to use a syntax like this:

void doConditional(int param1, int param2)
{
    MyAction<int,&::operator>=> action(param1,param2);
    if(action())
    {
        // Do this
    }
    else
    {
        // Do that
    }
}

But that doesn't compile:

error: ‘::operator>=’ has not been declared

What can I do to refer to such intrinsic static operations?

like image 311
πάντα ῥεῖ Avatar asked Jul 14 '13 23:07

πάντα ῥεῖ


People also ask

How do you initialize a pointer to a function in C++?

You need to initialize a pointer by assigning it a valid address. This is normally done via the address-of operator ( & ). The address-of operator ( & ) operates on a variable, and returns the address of the variable. For example, if number is an int variable, &number returns the address of the variable number .

Can we declare a function that can return a pointer to a function of the same type?

Return Function Pointer From Function: To return a function pointer from a function, the return type of function should be a pointer to another function. But the compiler doesn't accept such a return type for a function, so we need to define a type that represents that particular function pointer.

Can we increment function pointer?

The only things you can do with a function pointer are read its value, assign its value, or call the function that it points toward. You cannot increment or decrement the address stored in a function pointer or perform any other arithmetic operations.


2 Answers

Built-in operators

Why you cannot have function pointers of them:

C++11, §13.6/1, [over.built]

The candidate operator functions that represent the built-in operators defined in Clause 5 are specified in this subclause. These candidate functions participate in the operator overload resolution process as described in 13.3.1.2 and are used for no other purpose.

Built-in operators (those for the built-in types) aren't real operator functions. So you can't have function pointer pointing to them. You also cannot invoke them using operator<(A,B) syntax. They only participate in overload resolution but the compiler will translate them directly into the appropriate asm/machine instruction without any kind of "function call".

The way to get around this issue:

user1034749 has already answered this question, but for completeness:

The standard defines a lot of function objects in §20.8, [function.objects], i.e.

  • Arithmetic operations
  • Comparisons
  • Logic operations
  • Bitwise operations

A function object is an object of a function object type. In the places where one would expect to pass a pointer to a function to an algorithmic template (Clause 25), the interface is specified to accept a function object. This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects.

C++11, §20.8.5, [comparisons]

  • equal_to
  • not_equal_to
  • greater, less
  • greater_equal
  • less_equal

Those are templated function objects which decay to the analogous operator in their operator() function. They can be used as function pointer arguments.

user1034749 is right, I want to state: There's no other way, these are completely equivalent in usage to 'raw' function pointers. Reference given.

Standard class type operators

You can use standard library operators as function pointers (which are present as "real functions").

But you'll have to refer to the respective instance of the template. The compiler will need appropriate hints to deduce the correct template.

This works for me on MSVC 2012 using operator+ of std::basic_string

template<class Test>
Test test_function (Test const &a, Test const &b, Test (*FPtr)(Test const &, Test const &))
{
   return FPtr(a, b);
}

int main(int argc, char* argv[])
{
   typedef std::char_traits<char> traits_t;
   typedef std::allocator<char> alloc_t;
   std::basic_string<char, traits_t, alloc_t> a("test"), b("test2");
   std::cout << test_function<std::basic_string<char, traits_t, alloc_t>>(a, b, &std::operator+) << std::endl;
   return 0;
}

If the template argument of test_function is left out to be deduced this will fail (at least for MSVC 2012).

like image 141
Pixelchemist Avatar answered Sep 29 '22 09:09

Pixelchemist


You can use the same solution as used in C++ standard library:

std::sort (numbers, numbers+5, std::greater<int>());

where greater is

template <class T> struct greater : binary_function <T,T,bool> {
    bool operator() (const T& x, const T& y) const {return x>y;}
};

in your case http://www.cplusplus.com/reference/functional/greater_equal/

About reference of built operator.

You can reference existing operator< for any class (of course if they are not private, protected or your class/function not friend). But opeator< for builtin types (bool, short, int, double) it is not possible reference. Event if not look at C++ standard you can see from my text above.

like image 28
fghj Avatar answered Sep 29 '22 09:09

fghj