Ожидаемое поведение при расширении пакета параметров шаблона во внутреннее объявление шаблонаC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Ожидаемое поведение при расширении пакета параметров шаблона во внутреннее объявление шаблона

Сообщение Anonymous »

Существует два сценария:
  • Вы можете использовать пакет параметров шаблона и расширить его во вложенное объявление шаблона параметров шаблона, не являющихся типом. :

Код: Выделить всё

template
struct Outer {
template
void inner(){}
};
Я думал, что это будет довольно просто, поскольку это технически возможно, начиная с C++11, но итоговое поведение сильно различается между компиляторами:
Вызов следующих функций-членов в переменная Outer external{}; приводит к следующему результату (Демо - прокомментируйте определенные строки в main, чтобы увидеть выводит компилятор):

Код: Выделить всё

outer.inner();
:
  • GCC: ошибка: неправильное количество аргументов шаблона (2, должно быть 1)
  • clang: компилируется
  • MSVC: компилируется

Код: Выделить всё

outer.inner();
:
  • GCC: ошибка: неправильное количество аргументов шаблона (2, должно быть 1)
  • clang: шаблон-кандидат игнорируется: недопустимый явно указанный аргумент для параметра шаблона «Vals»
  • MSVC: не удалось специализировать шаблон функции «void Outer::inner(void)' (за которым следует ICE)

Код: Выделить всё

outer.inner();
:
  • GCC: ICE
  • clang: шаблон-кандидат игнорируется: выведено слишком мало аргументы в пользу расширенного пакета «Валс»; нет аргумента для второго расширенного параметра в пакете выведенных аргументов
  • MSVC: компилируется

Код: Выделить всё

outer.inner();
:
  • GCC: компилируется
  • clang: шаблон-кандидат игнорируется: выведено слишком мало аргументов для расширенного пакета 'Вальс'; нет аргумента для первого расширенного параметра в выведенном пакете аргументов
  • MSVC: компилируется
Пока clang ведет себя так, как я лично ожидал, несоответствие между компиляторами заставляет меня думать, что я делаю что-то, что официально не разрешено (может быть, расширение clang?), так что же, согласно официальному стандарту, здесь должно происходить?
  • Благодаря концепциям C++20 теперь синтаксически допустимо(?) расширять пакет параметров шаблона во вложенный список аргументов шаблона с использованием ограниченного типа. параметры.

Код: Выделить всё

template
concept At = true;

template
struct Outer{
template
void inner(Ts...){}
};
Вызов следующих функций-членов для переменной Outer external{}; приводит к следующему результату (Демо — прокомментируйте определенные строки в main< /code>, чтобы увидеть выходные данные компилятора):

Код: Выделить всё

outer.inner(0, 1);
:
  • GCC: компилируется
  • clang: компилируется
  • MSVC: компилируется

Код: Выделить всё

outer.inner(0, 1, 2);
:
  • GCC: ошибка: несоответствующая длина пакета аргументов при расширении «At»
  • clang: функция-кандидат [с Ts = ] нежизнеспособна: требуется 2 аргумента, но предоставлено 3
  • MSVC: связанный ограничения не выполняются

Код: Выделить всё

outer.inner(0);
:

[*]GCC: ошибка: несоответствующая длина пакета аргументов при расширении «At»[*]clang: шаблон-кандидат игнорируется: выведено слишком мало аргументов для расширенного пакета «Ts»; нет аргумента для второго расширенного параметра в выведенном пакете аргументов
[*]MSVC: связанные ограничения не удовлетворены

Здесь я предполагаю, что GCC и MSVC верны, поскольку они, кажется, ведут себя так же, как и при переписании from, и в этом случае clang также ведет себя как GCC и MSVC (Демо):

Код: Выделить всё

template
struct Outer{
template
requires (At && ...)
void inner(Ts...){}
};
Но clang, кажется, создает своего рода пакет параметров фиксированной длины, который позволяет реализовать некоторые интересные сценарии, например ведущие пакеты (демо):

Код: Выделить всё

template
struct Outer{
template
void inner(Ts..., U){}
};

int main() {
Outer outer{}.inner(true, 1, 2.0);
}
Который компилируется с помощью clang и выводит Ts = и U = double.
Итак, вопрос еще раз, какое поведение является правильным согласно стандарту?

Подробнее здесь: https://stackoverflow.com/questions/791 ... ner-templa
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»