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

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).

Leave a Comment