我有这个代码,其中我试图从传递的参数中获取最大数字。由于某种原因,它不起作用,我不确定为什么。当我输入2个数字时代码有效,但当传递3个或更多时,我得到这些错误:
prog.cpp:在函数'int main()'中:
prog.cpp:31:29:错误:没有匹配函数来调用'max(int,int,int)' prog.cpp:31:29:注意:候选人是:
prog.cpp:24:30:注意:模板constexpr decltype(handle :: helper :: max(max :: args ...))max(Args ...)
prog.cpp:24:30:注意:模板参数扣除/替换失败:
prog.cpp:替换'template constexpr decltype(handle :: helper :: max(args ...))max(Args ...)[with Args = {int,int,int}]':
prog.cpp:31:29:从这里要求
prog.cpp:24:30:错误:没有匹配函数来调用'handle :: helper :: max(int&,int&,int&)'
prog.cpp:24:30:注意:候选人是: prog.cpp:11:18:注意:static T handle :: helper :: max(T,T)[with T = int; Args = {int,int}]
prog.cpp:11:18:注意:候选人需要2个参数,3个提供了 prog.cpp:16:18:注意:static T handle :: helper :: max(T,T,Args ...)[with T = int; Args = {int,int}]
prog.cpp:16:18:注意:候选人需要4个参数,3个提供
以下是该计划:
#include <iostream>
namespace handle
{
template <typename... Args>
struct helper {};
template <typename T, typename... Args>
struct helper<T, Args...>
{
static T constexpr max(T x, T y)
{
return x > y ? x : y;
}
static T constexpr max(T x, T y, Args... args)
{
return max(x, max(y, args...));
}
};
}
template <typename... Args>
static auto constexpr max(Args... args) -> decltype(handle::helper<Args...>::max(args...))
{
return handle::helper<Args...>::max(args...);
}
int main()
{
std::cout << max(5, 3, 7); // fails
}
我真的很困惑,因为我以为我把它弄下来了。我做错了什么,我该如何解决?感谢。
更新:谢谢命名。由于此问题现已解决,因此结果如下:
#include <type_traits>
#include <iostream>
namespace handle
{
template <typename T, typename V>
static auto constexpr max(T const& x, V const& y)
-> typename std::common_type<T, V>::type
{
return x > y ? x : y;
}
template <typename T, typename V, typename... Args>
static auto constexpr max(T const& x, V const& y, Args const&... args)
-> typename std::common_type<T, typename std::common_type<V, Args...>::type>::type
{
return max(x, max(y, args...));
}
}
template <typename... Args>
static auto constexpr max(Args const&... args) -> decltype(handle::max<Args...>(args...))
{
return handle::max<Args...>(args...);
}
int main()
{
std::cout << max(5, 3, 7.8, 2, 4, 55); // 55
}
谢谢大家!
答案 0 :(得分:7)
Morwenn指出了你的问题。 但是,您仍然可以将代码简化为此。 (你确实可以在C ++ 11中专门化函数模板)
namespace handle
{
template <typename T, typename V>
static auto max(const T& x, const V& y)
-> typename std::common_type<T,V>::type
{
return x > y ? x : y;
}
template <typename T, typename V, typename... Args>
static auto max(const T& x, const V& y, const Args&... args)
-> decltype( max(x, max(y, args...)) )
{
return max(x, max(y, args...));
}
}
int main()
{
std::cout << handle::max(1,2,3.3);
}
这样做的好处是在比较不同类型时返回正确的类型。
编辑:当你有超过3个args的时候,这不会起作用。问题似乎是gcc
在评估
max
本身
decltype(max(y, args...)
您可以妥协并使用此代替
template <typename T, typename V, typename... Args>
static auto max(const T& x, const V& y, const Args&... args)
-> typename std::common_type<T, V>::type
{
return max(x, max(y, args...));
}
评论中的0x499602D2建议的更好的方法
template <typename T, typename V, typename... Args>
static auto max(const T& x, const V& y, const Args&... args)
-> typename std::common_type<T, V, Args...>::type
{
return max(x, max(y, args...));
}
编辑:使用gcc
的{{1}}标记(允许您发出尾随返回类型),您可以这样做。 (上面的案例绝对是一个错误)
-std=c++1y
答案 1 :(得分:1)
一个问题是论证是错误的。您正在呼叫helper<int,int,int>::max
。在您的模板中:
template <typename T, typename... Args>
struct helper<T, Args...>
{
constexpr static T max(T x, T y)
{
return x > y ? x : y;
}
constexpr static T max(T x, T y, Args... args)
{
return max(x, max(y, args...));
}
};
Args
变为int,int
,因此您最终得到一个带有两个参数的max
函数,以及一个带有四个参数的max
函数,但没有一个带三个参数参数。
但是,它并不像删除其中一个参数那么简单:
constexpr static T max(T x, Args... args)
{
return max(x, max(args...));
}
因为现在你的函数与max(x,y)
变得不明确。
你可以做的是提供这样的专业化:
template <typename T>
struct helper<T> {
static T max(T x) { return x; }
};
template <typename X,typename Y,typename... Args>
struct helper<X,Y,Args...> {
constexpr static X max(X x,Y y,Args... args)
{
return std::max(x,helper<Y,Args...>::max(y,args...));
}
};