Параметры шаблона по умолчанию в описании использования и создании экземпляра

Редактировать:
По-видимому, GCC позволяет создать экземпляр шаблона класса без списка параметров (когда параметры заданы по умолчанию), что не соответствует требованиям (соответствует требованиям Clang) .
Я предполагаю, что причина, по которой требуются скобки (даже если список параметров пуст), заключается в том, чтобы явно указать, что это экземпляр шаблона, а не фактический тип. Итак, я задаю свой исходный вопрос о различиях между случаями шаблона класса и шаблона функции: почему во втором фрагменте разрешено вызывать a без скобок, в отличие от экземпляра A в первом фрагменте? А почему это не разрешено для b?


Оригинал:
A class template with only default parameters can be instantiated without any parameter list (see A below).
However, if an alias to that class template is defined via a using-declaration as a template with the same default parameters (see B below), then its instantiation requires a parameter list (possibly empty).
Similarly, defining an alias to the class template as an actual type (see C below) requires a parameter list (again, possibly empty).
Is there a reason behind this?
template<int i = 1>
struct A {
    operator int() { return i; }
};

template<int i = 2>
using B = A<i>;

// using C = A;    <-- error: missing template arguments after 'A'
using C = A<>;

int main() {
    A a; // Edit: Actually should require brackets: A<> a;
    // B b;    <-- error: missing template arguments before 'b'
    B<> b;
    C c;
}

В прямом эфире на Колиру

Я попытался создать аналогичный сценарий с шаблоном функции вместо шаблона класса, и в последнем случае (C) есть небольшая разница: список параметров не требуется, если тип возвращаемого значения указан в определении a. Думаю, я понимаю почему, но я хотел бы получить некоторые идеи. В остальном оба случая аналогичны шаблонным классам.

template<int i = 1>
auto a() { return i; }
// auto a() -> int { return i; }
// if the return type is specified, c can be defined as commented below

template<int i = 2>
auto b = a<i>;

// auto c = a;    <-- error: unable to deduce 'auto' from 'a'
auto c = a<>;

int main() {
    a();
    // b();    <-- error: missing template arguments before '(' token
    b<>();
    c();
}

В прямом эфире на Колиру

Кроме того, есть ли существенные различия между современными стандартами C++ (от C++ 11 до C++ 20)? Меня больше всего интересует случай C++ 17, но я хотел бы знать, изменились ли эти вещи или собираются ли они. Из того, что я видел, в C++ 14 для создания экземпляра шаблона класса в любом случае требуется список параметров, а для вызова шаблона функции - нет. И я не нашел различий между C++ 17 и C++ 2a с GCC.

Coliru использует немного устаревший clang (5.0.0, последняя версия - 7.0.0), который не реализует некоторые отчеты о дефектах, касающиеся CTAD.

cpplearner 12.10.2018 12:22

@cpplearner Я не совсем понимаю, на какую часть это должно повлиять. Clang кажется мне послушным?

Nelfeal 12.10.2018 12:41

Какой clang, clang 5.0.0 или clang 7.0.0 (что позволяет использовать A a;)?

cpplearner 12.10.2018 13:26

@cpplearner О, значит, Clang 7.0.0 допускает то же самое, что и GCC, что не соответствует требованиям? Это просто то, что оба компилятора добавили для удобства, или это ошибка в обоих? Или это действительно допускается стандартом?

Nelfeal 12.10.2018 14:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
4
553
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Аргументы шаблона [temp.arg] / 4 (§12.3 / 4)

When template argument packs or default template-arguments are used, a template-argument list can be empty. In that case the empty <> brackets shall still be used as the template-argument-list.

Такая же формулировка для C++ 17 в §17.3 / 4, для C++ 14 и C++ 11 в §14.3 / 4.

Явная спецификация аргумента шаблона [temp.arg.explicit] (§12.9.1 / 3):

If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.

Такая же формулировка для C++ 17 в §17.8.1 / 3, для C++ 14 и C++ 11 в §14.8.1 / 3.


Ваш

template<int i = 2>
auto b = a<i>;

- это шаблон переменных, для которого не выполняется вывод аргументов.

Так это «ошибка» GCC, позволяющая опустить скобки? А как насчет случая шаблона функции?

Nelfeal 12.10.2018 11:41

Хорошо, это действительно похоже на ошибку с GCC, поскольку Clang не допускает ее в случае шаблона класса. Однако это касается шаблонов функций. Есть ли причина такой разницы?

Nelfeal 12.10.2018 11:51

Может быть, добавьте еще один простой пример того, что позволяет clang и о чем вы беспокоитесь в своем вопросе? Кстати. Вы в курсе, что auto c = a<>; определяет указатель функции a?

Swordfish 12.10.2018 11:54

Я знаю, что c - указатель на функцию (как и b). Есть что-нибудь ближе к псевдониму для функций?

Nelfeal 12.10.2018 12:15

@Nelfeal Не совсем. Просто попросил убедиться. Однако ваш b - это шаблон переменной.

Swordfish 12.10.2018 12:40

Итак, если я правильно понимаю, разница на самом деле заключается между тремя случаями: шаблонами классов, шаблонами функций и шаблонами переменных. И по какой-то причине экземпляры шаблонов функций - единственные, которые не требуют скобок при выводе аргументов. А если есть значения по умолчанию, то аргументы действительно выводятся. Это верно?

Nelfeal 12.10.2018 12:49

@Nelfeal AFAICT Да.

Swordfish 12.10.2018 13:03

Другие вопросы по теме