Search code examples
c++c++14variadic-templatesoverload-resolution

How to avoid an invalid overload from the std library?


In my C++14 project I'm using

#include <algorithm>
using std::max;            // for max(a,b)

but I also want to provide a max() function taking any number of arguments (of equal type). To this end, I added

template<typename T, typename...A>
constexpr inline T const& max(T const&x, T const&y, A...&&z)
{
    return max(max(x,y), std::forward<A>(z)...);
}

but upon a call like

double x,y,z;
...
auto m = max(x,y,z);

the compiler tries to instead of my overload use

namespace std {
template< class T, class Compare >
constexpr const T& max( const T& a, const T& b, Compare comp );
}

from algorithm. How can I avoid that (but still provide the intended functionality)?

(Note that there is a question about variadic min/max, but it doesn't address the issue I have by simply changing the name to vmin/vmax.)


Solution

  • The problem can be solved by only overloading the function for 3 or more arguments like:

    template<typename T, typename...A>
    constexpr inline T const& max(T const&x, T const&y, T const&z, A&&...w)
    {
        return max(max(x,y), z, std::forward<A>(w)...);
    }