如何避免std库中的无效重载?

问题描述

在我正在使用的C ++ 14项目中

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

但是我还想提供一个max()函数,该函数接受任意数量的参数(相同类型)。为此,我添加了

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

但在接到类似电话

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

编译器尝试代替我的重载使用

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

来自algorithm。如何避免这种情况(但仍提供预期的功能)?

(请注意,这里有一个question about variadic min/max,但仅通过将其名称更改为vmin / vmax并不能解决我遇到的问题。)

解决方法

可以通过仅重载3个或更多参数的函数来解决问题,例如:

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)...);
}
,

你没有。

要么停止using std::max并改为限定您的名称空间,要么将函数命名为其他名称。

,

如评论中所述,您可以简单地使用带有初始化列表的std::max

一个示例调用为:

auto maxNum = std::max({a,b,c});
,

我建议yao99的答案应该被接受。出于好奇,我在这里为您提供一个通过您自己的名称空间提供适配器的解决方案。它仅使用std::max的二进制参数重载,因此没有可能调用初始化程序列表重载。客户端代码仍可以按照指示使用max

适配器:

#include <iostream>
#include <algorithm>

namespace variadicMax
{
    // the variadic "max" recurses and reduces to a binary parameter version that we must implement
    template<typename T>
    constexpr inline T const& max(T const&x,T const&y)
    {
        return (std::max(x,y));
    }

    // the variadic overload recurses itself,removing two parameters (and adding one) each time.
    // Eventually it reduces to (x,y) which is handled by the other overload.
    template<typename T,typename...Args>
    constexpr inline T const& max(T const&x,Args&&...z)
    {
        return (max (std::max(x,std::forward<Args>(z)...));
    }
};

客户:

// this is the only change needed in clients:
using variadicMax::max;

int main()
{
    double x,y,w,v;

    x = 1;  y = 2;  z = 3;  w = 4;  v = 5;
    auto m5 = max(x,v);  std::cout << m5 << std::endl;
    auto m5A = max(x,4.0,v);  std::cout << m5A << std::endl;

    x = 1;  y = 2;  z = 3;
    auto m = max(x,z);  std::cout << m << std::endl;

    x = 2;  y = 3;  z = 1;
    auto m2 = max(x,z);  std::cout << m2 << std::endl;

    x = 3;  y = 2;  z = 1;
    auto m3 = max(x,z);  std::cout << m3 << std::endl;

    x = 3;  y = 2;
    auto m4 = max(x,y);  std::cout << m4 << std::endl;

    x = 3;  y = 2;
    auto m6 = max(3,2);  std::cout << m6 << std::endl;

    x = 3;  y = 2;
    auto m7 = max(x,2.0);  std::cout << m7 << std::endl;

    etc...

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...