Когда можно опускать пустые угловые скобки?
В этом вопросе можно использовать std::less с пустыми скобками std::less<>, но нельзя без них std::less. В то время как этот код принимает оба варианта:
std::sort(v.begin(), v.end(), std::less());
std::sort(v.begin(), v.end(), std::less<>());
Почему так? Когда можно опустить <>, а когда нельзя?
Ответы (1 шт):
std::less - шаблон класса. Возможность не писать после него шаблонные аргументы называется CTAD (class template argument deduction - вывод аргументов для шаблонов классов).
В общем случае это позволяет не только убирать <>, но и угадывать шаблонные аргументы из аргументов конструктора.
Ищем "class template argument deduction" в предметном указателе стандарта, находим:
If a placeholder for a deduced class type appears as a decl-specifier in the decl-specifier-seq of an initializing declaration ([dcl.init]) of a variable, the declared type of the variable shall be cv T, where T is the placeholder.
Т. е. первый случай - это разрешено в "инициализирующих объявлениях" переменных, если в типе кроме имени класса нет ничего кроме const и volatile (никаких *, [], и т. п.).
Что еще за "инициализирующее объявление"? [dcl.init.general]/21 объясняет, что это то же самое, что определение переменной, за исключением вот этой ситуации:
struct A {static const int x = 1;};
const int A::x;
В которой инициализирующее объявление - первое (потому что там инициализатор), а определение - второе.
Но это не единственный случай, где это разрешено. Читаем дальше:
A placeholder for a deduced class type can also be used in the type-specifier-seq in the new-type-id or type-id of a new-expression ([expr.new]), as the simple-type-specifier in an explicit type conversion (functional notation), or as the type-specifier in the parameter-declaration of a template-parameter ([temp.param]). A placeholder for a deduced class type shall not appear in any other context.
Т. е. еще это разрешено в:
- Вызовах
new. - C-style кастах в фунциональной записи, т.е.
класс(...)можно, а(класс)...нельзя. - В типах NTTP (non-type template parameters - шаблонных параметров, не являющихся типами). На этом основана возможность передавать строки в шаблонные параметры.