在任意加长的集合中查找最大数量不起作用

tem*_*boy 2 c++ templates c++11

我有这个代码,其中我试图从传递的参数中获取最大数字.由于某种原因,它不起作用,我不确定为什么.当我输入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:注意:静态T句柄:: helper :: max(T,T)[T = int; Args = {int,int}]
prog.cpp:11:18:注意:候选人需要2个参数,3个提供
prog.cpp:16:18:注意:static T handle :: helper :: max(T,T,Args ...)[与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
}
Run Code Online (Sandbox Code Playgroud)

我真的很困惑,因为我以为我有这个.我做错了什么,我该如何解决?谢谢.


更新:谢谢命名.由于此问题现已解决,因此结果如下:

#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
}
Run Code Online (Sandbox Code Playgroud)

谢谢大家!

sta*_*ust 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); 
}
Run Code Online (Sandbox Code Playgroud)

这具有在比较不同类型时返回正确类型的优点.


编辑:一般来说,当你有超过3个args时,这将不起作用.问题似乎是在评估时gcc不考虑变量max本身

decltype(max(y, args...) 
Run Code Online (Sandbox Code Playgroud)

您可以妥协并使用它

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...));
}
Run Code Online (Sandbox Code Playgroud)

注释中由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...));
}
Run Code Online (Sandbox Code Playgroud)

编辑:随着gcc-std=c++1y标志(它允许您发出尾随返回类型),你可以做到这一点像.(上面的情况肯定是一个错误然后)

template <typename T, typename V>
auto max(const T& x, const V& y) {
    return x > y ? x : y;
}

template <typename T, typename V, typename... Args>
auto max(const T& x, const V& y, const Args&... args) {
    return max(x, max(y, args...));
}
Run Code Online (Sandbox Code Playgroud)