Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get the function pointer of a built-in standard operator?

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 400
πάντα ῥεῖ Avatar asked Jul 14 '13 23:07

πάντα ῥεῖ


People also ask

Is it possible to declare function pointer in structure?

Function pointers can be stored in variables, structs, unions, and arrays and passed to and from functions just like any other pointer type. They can also be called: a variable of type function pointer can be used in place of a function name.

Is array of function pointer is possible in C?

In C, we can use function pointers to avoid code redundancy. For example a simple qsort() function can be used to sort arrays in ascending order or descending or by any other order in case of array of structures. Not only this, with function pointers and void pointers, it is possible to use qsort for any data type.

How a pointer to a function is declared in C?

Master C and Embedded C Programming- Learn as you go A pointer is a variable whose value is the address of another variable or memory block, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable or block address.


1 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 79
Pixelchemist Avatar answered Sep 30 '22 18:09

Pixelchemist