Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Failed to create function aliases C++

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading