Failed to create function aliases C++

Advertisements

I’m trying to create a shorter name for an existing function.
When I use variable templates type deduction fails

#include <iostream>
#include <cmath>


template<class T>
constexpr T (*max)(T, T) = std::fmax<T>;


int main(){
    
    double x = 6.28;
    double y = 4.45;
    
    std::cout << (max<int>(x, y)) << std::endl;
    
    
}

This is the message from the compiler:

<stdin>:6:28: error: address of overloaded function 'fmax' does not match required type 'int (int, int)'
constexpr T (*max)(T, T) = std::fmax<T>;
                           ^~~~~~~~~~~~
<stdin>:14:16: note: in instantiation of variable template specialization 'max<int>' requested here
        std::cout << (max<int>(x, y)) << std::endl;
                      ^
/data/user/0/ru.iiec.cxxdroid/files/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/math.h:1200:1: note: candidate template ignored: failed template argument deduction
fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
^

Without using the alias, the call does work

std::cout<< std:fmax<int>(x, y) << std::endl;

>Solution :

Taking addresses of standard library functions is (with few exceptions) not guaranteed to work at all. The standard library is allowed to use different overload sets of templates to implement the specified behavior of calls to std::fmax. And even the standard specifies fmax not as a single template with one template parameter, but as multiple overloads, one of which would naively have two template parameters and the rest none.

Instead just define a function calling the other one:

template<class T>
constexpr auto max(T a, T b) {
    return std::fmax(a, b);
}

Also:

  • constexpr is wrong before C++23, since std::fmax is constexpr only since C++23
  • I’d advice against using max as name. There are functions with the name max in the standard library. These do behave differently (returning a reference to one of the arguments instead of a copy by-value and having different floating point behavior). This can easily be confusing.
  • There are overloads of std::fmax that allow two differently typed arguments, so your function should probably also accept different types for the parameters.
  • The behavior is not exactly correct if you specify the return type as T. There is a specified overload of fmax which may return a different type.
  • It is probably not a good idea to alias this at all. I don’t really see a good reason for doing so.

Leave a ReplyCancel reply