参数包

时间:2015-12-28 13:16:20

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

这是标准std::max函数的扩展,因此可以使用随机数量的参数。

template<typename T, typename U, typename Compare = std::greater<>> constexpr
const auto max(const T& first, const U& second, Compare comp = Compare())
{
    return comp(first, second) ? first : second;
}

template<typename T, typename U, typename... Pack, typename Compare = std::greater<>> constexpr
const auto max(const T& first, const U& second, const Pack&... rest, Compare comp = Compare())
{
    return comp(first, second) ? max(first, rest..., comp) : max(second, rest..., comp);
}

据我所知,comp参数将取我调用该函数的最后一个参数的值。

我错了吗?我该怎么办呢?

std::cout << max(2, 3, 4, 5); //boom
std::cout << max(2, 3, 4, 5, std::greater<>()); //boom

当然,如果我完全删除comp,它的工作正常。

1 个答案:

答案 0 :(得分:2)

rest的类型是非推断的上下文,因此编译失败,因为找不到对max的调用的匹配函数(有关背景信息,请参阅What is a non-deduced context?):

example.cpp:18:18: error: no matching function for call to 'max'
    std::cout << max(2, 3, 4, 5); //boom
                 ^~~
example.cpp:5:12: note: candidate function template not viable: requires at most 3 arguments, but 4
      were provided
const auto max(const T& first, const U& second, Compare comp = Compare())
           ^
example.cpp:11:12: note: candidate function not viable: requires at most 3 arguments, but 4 were
      provided
const auto max(const T& first, const U& second, const Pack&... rest, Compare comp = Compare())

没有简单的解决方案可以避免这种情况。您可以考虑以下解决方法之一:

  1. Compare参数作为第一个参数
  2. 传递
  3. 使用initializer_list传递参数(因此,所有类型都相同)
  4. 在C ++ 14标准中,他们选择了第二个选项:

    template< class T, class Compare >
    T max( std::initializer_list<T> ilist, Compare comp )
    {
        return *std::max_element(ilist.begin(), ilist.end(), comp);
    }
    

    来源:http://en.cppreference.com/w/cpp/algorithm/max