Заполнители шаблонов C++ не разрешены в аргументах функции

В следующем коде C++ заполнитель шаблона в аргументе функции fun1 и в возвращаемом типе функции ret1 не компилируется:

template <typename T = int>
class type {
    T data;
};

void fun1(type      arg); // Error: template placeholder not permitted in this context 
void fun2(type<>    arg); // Ok
void fun3(type<int> arg); // Ok

type      ret1(); // Error: Deduced class type 'type' in function return type
type<>    ret2(); // Ok
type<int> ret3(); // Ok

int main() {
    type      var1;  // Ok!!!!!!
    type<>    var2;  // Ok
    type<int> var3;  // Ok
}

Но var1 это нормально.

  • Почему var1 компилируется, а fun1 и ret1 нет?
  • Есть ли какая-то логика за этим непоследовательным поведением между объявлениями функций и объявлениями переменных?
Стоит ли изучать 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
0
166
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

var1 выигрывает от CTAD, где все нестандартные аргументы шаблона (т. е. ни одного) могут быть выведены из инициализации. Однако оба объявления функций не являются кандидатами для CTAD, поэтому список аргументов шаблона должен быть предоставлен, даже если этот список пуст.

Вычет за шаблоны классов

Неявно генерируемые руководства по дедукции

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

(выделение добавлено)

type var1; использует вывод аргумента шаблона класса (CTAD), который возможен, начиная с C++ 17, и выводит аргументы шаблона из инициализатора переменной (здесь пустой список аргументов).

Это невозможно в объявлении функции, потому что нет инициализатора, из которого можно вывести аргументы шаблона.

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

Для возвращаемого типа его можно было указать аналогично тому, как работает тип возвращаемого значения auto, но это просто не было сделано при внедрении CTAD.

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