【问题标题】:Variadic template max function troubleVariadic模板Max功能麻烦
【发布时间】:2012-01-14 04:24:03
【问题描述】:

我正在尝试编写一个可变参数模板来查找任意数量的最大值(这只是为了练习可变参数模板)。

但是,我有点碰壁,无法理解为什么我当前的尝试根本不起作用,并且在编译时失败并出现错误:

prog.cpp: In function 'A myMax(A, A, Args ...) [with A = int, Args = {}]':
prog.cpp:7:35:   instantiated from 'A myMax(A, A, Args ...) [with A = int, Args = {int}]'
prog.cpp:22:26:   instantiated from here
prog.cpp:7:35: error: no matching function for call to 'myMax(int)'

我的代码如下:

#include <iostream>

template <typename A, typename ... Args>
A myMax(A a, A b, Args ... args)
{
   return myMax(myMax(a,b),args...);
}

template <typename A>
A myMax(A a,A b)
{
   if (a>b)
      return a;
   else
      return b;
}


int main()
{
   std::cout<<myMax(1,5,2);
}

谁能告诉我如何修复我的可变参数模板?

【问题讨论】:

  • 好的,但是一旦你完成了学习,请返回并使用std::max :-)

标签: c++ templates c++11 variadic-functions


【解决方案1】:

只需在可变参数函数模板上方定义带两个参数的重载:

template <typename A> 
A myMax(A a,A b)      //this is an overload, not specialization
{
   if (a>b)
      return a;
   else
      return b;
}

template <typename A, typename ... Args>
A myMax(A a, A b, Args ... args)
{
   return myMax(myMax(a,b),args...);
}

现在它可以工作了:http://www.ideone.com/R9m61

重载应该在可变参数函数模板中的实例化点可见。

【讨论】:

  • 哇,这对我来说是一个令人惊讶的答案。很简单!我期待关于部分专业化与重载的更复杂的东西。在#include &lt;iostream&gt; 之后添加函数签名也可以吗?例如:template &lt;typename A&gt; A myMax(A a, A b);
【解决方案2】:

使用std::maxprevious answer 的较短变体,试试here

#include <iostream>

template <typename T> 
T Max(T a) 
{
    return a;
}

template <typename T, typename ... Args> 
T Max(T a, Args ... args) 
{
    return std::max(Max(args...), a);
}

int main() {
    std::cout << Max(14,45,87,66,99,888,554,21);
}

【讨论】:

  • 不要说“上面”,因为您无法确定答案的顺序,或者哪些答案不会被删除。相反,请通过其下方的共享链接链接到答案。
【解决方案3】:

使用constexpr,现在可以执行以下操作:

template<typename num_t, num_t ...X>
constexpr num_t max_element(){
    const std::array<num_t, sizeof...(X)> vals{X...};
    num_t ret = 0;
    for(size_t i=0; i<sizeof...(X); i++)
        if(vals[i] > ret)
            ret = vals[i];
    return ret;
}

我尝试更进一步,简单地使用:

const std::array<num_t, sizeof...(X)> vals{X...};
return *std::max_element(vals.cbegin(), vals.cend());

但编译器抱怨(我完全忘记了它所说的内容。[编辑:参见this question/answer,它更一般地解释了 std::allogrithm 的情况。]

不管怎样,你只是把它当作:

auto max_val =  max_element<int, 11, 88, 12, 2>();
assert(max_val == 88);

【讨论】:

    【解决方案4】:
    template<class T>
    T Max(T a, T b)
    {
        return (a > b ? a : b);
    }
    
    template<class T, class... a>
    T Max(T x , a... z)
    {
        T k = Max(z...);
        return (x > k ? x : k);
    }
    
    int main()
    {
        cout << Max(14,45,87,66,99,888,554,21);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2013-10-30
      相关资源
      最近更新 更多