2015-12-28 2 views
0

Это расширение стандартной функции 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 полностью.

+3

'rest' находится в невыводимом контексте. (Это во многом почему «вариационная» версия 'std :: max' принимает' initializer_list'.) –

+6

Таким образом, это непрактично. Попробуйте что-нибудь еще. (Я могу заставить ваш код работать, но он включает в себя sfinae гимнастику и метапрограммирование, и даже тогда, если у вас есть параметр, который поддерживает '()' и '<' it breaks). Сделайте версию сравнения имеющей другое имя и сначала сравните ее. – Yakk

ответ

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. Использование initializer_list передать аргумент (таким образом, все будут иметь один и тот же тип)

В стандарт 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

Смежные вопросы