问题描述
在我正在使用的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...