typename
- это ;пример программы плохо сформирован.Если компилятор не диагностирует проблему, он не соответствует стандарту.Правильная версия:
typename C::const_iterator * iter1 = new typename C::const_iterator(cont.begin());
// ^^^^^^^^ this one only required until C++20
typename C::const_iterator iter2 = cont.begin();
Стандартная цитата (черновик для C ++ 17):
[temp.res]
Имя, используемое вобъявление шаблона или определение, и это зависит от atemplate-parameter, как предполагается, не называет тип, если применимый поиск имени не находит имя типа или имя квалифицируется ключевым словом typename
.
C::const_iterator
зависит от шаблона-параметра C
, поэтому его не следует считать именем типа, если не используется typename
.Я думаю, что это утверждение следует интерпретировать как операцию умножения, но правый операнд является необъявленным идентификатором и поэтому неправильно сформирован.
C ++ 20 вводит правило, позволяющее удалить typename
из выражения new(последний черновик):
[temp.res]
Говорят, что квалифицированное имя находится в контексте только с идентификатором типа, если оно появляется в идентификаторе типа, new-type-id , или определяющий-тип-идентификатор, а наименьший включающий идентификатор типа, новый-тип-идентификатор или определяющий-тип-идентификатор - это новый-тип-идентификатор, определяющий-тип-идентификатор, тип конечного возврата, аргумент по умолчанию для параметра типа шаблона или идентификатор типа для static_cast, const_cast, reinterpret_cast или dynamic_cast.
Возможно, вы захотите создатьпсевдоним типа для читабельности:
using const_iterator = typename C::const_iterator;
Или вы можете просто использовать auto
:
auto it = cont.begin();
PS Вряд ли когда-либо имеет смысл динамически выделять итератор.