Как Concepts-Lite взаимодействует с вариативными шаблонами?

Я смотрел Bjarne Strustrup в Going Native 2013, и он приводит следующий пример для предстоящей концепции-Lite-функции С++.

void sort(Container& c); // terse notation

// Expands to
template <Container __Cont>
  void sort(__Cont& c); // shorthand notation

// Expands to 
template <typename __Cont>
  requires Container<__Cont>()
    void sort(__Cont & c);

Мой вопрос в том, как это будет работать с вариационными шаблонами?

Скажем, я хочу определить вариационную функцию maximum, используя концепцию Comparable. Будет ли принят следующий синтаксис?

auto maximum(Comparable a)
{
     return a;
}

auto maximum(Comparable c, Comparable... rest)
{        
    return std::max(a, maximum(rest...));
}

Если это так, то Comparable... означает, что все элементы в пакете параметров являются одним и тем же типом или просто все типы Comparable, так что пакет может включать в себя как int, так и string? (которые оба сопоставимы, но не друг с другом)

Любопытные умы хотят знать.

Ответ 1

Я считаю, что намерение краткого формата состоит в том, чтобы потребовать, чтобы все элементы в пакете были одного типа. Это выведено из примера в n3701, раздел 5.3, в котором говорится, что

void sort(Random_access_iterator p, Random_access_iterator q);

должен быть эквивалентен

template<Random_access_iterator __Ran>
void sort(__Ran p, __Ran q);

потому что

"По умолчанию, если вы используете один и тот же параметр с ограничением имя типа для двух аргументов, типы этих аргументов должны быть одинаковыми. Мы решили многократно использовать имя типа ограниченных параметров." тот же тип ", потому что это (в большинстве сред) является наиболее распространенным случаем, было бы странно иметь идентификатор, используемый дважды в области, иметь два разных и целью здесь является оптимизация для краткой записи простейшего случая".

Но я не вижу, как он может быть расширен в ваш maximum с синтаксисом текущего ('14) шаблона. В предлагаемом изменении стандартной формулировки в n3701 речь шла только о простом случае

& sect; 7.1.6.5 Спецификаторы ограниченных типов [dcl.spec.constrained]

...

Первое использование понятия-имени или частичного понятия-идентификатора в рамках области связывает это имя к типу заполнителя, чтобы последующие виды использования с тем же именем ссылались на тот же тип.

Но это не объясняет взаимодействие вариаций. Возможно, нужно дождаться 3-го пересмотра, чтобы прояснить это.

Ответ 2

Я не знаю, является ли N3580 последней версией концептуального документа, но в 4.5.1, как представляется, описывается, как требования типа могут использоваться с переменные списки аргументов. Кажется, что

template <Comparable... T>
auto maximum(T... values) -> <return-type-goes-here>

потребовалось бы, чтобы каждый из аргументов удовлетворял требованию Comparable, но нет ограничений на то, что типы T... все одинаковы. Это требование необходимо будет устанавливать отдельно. Вне рук, единственный способ, которым я мог бы навязывать однотипное требование, - это тот же подход, что и в С++ 11, но возможности концепций могут иметь лучший подход.