Чтобы было понятно о чем идет речь, рассмотрим конкретный пример:
template<typename T> struct A {
template<int I> void f() {}
};
template<typename TT> void g()
{
A<TT> a;
a.f<3>(); // error is here
}Код выглядит корректным, однако, строка, где указана ошибка, рассматривается компилятором как выражение со знаком меньше. Интересно, что Visual C++ 2008 догадывается, что там на самом деле (другие компиляторы не настолько догадливы). Однако стандарт С++ говорит о том, что нужно явно указывать компилятору на наличие вызова шаблонной функции там. Об этом говорит пункт 14.2/4. Правильная запись показана ниже:template<typename TT> void g()Слово template выглядит довольно неожиданно в этом месте, что приводит в замешательство не только новичков. Тем более, что Visual C++ игнорирует стандарт по непонятной причине. В будущем стандарте требование ключевого слова остается.
{
A<TT> a;
a.template f<3>(); // correct
}
C++'03 Standard 14.2/4:
When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
Мда, какой неожиданный изврат...
ОтветитьУдалитьВероятно стоило бы относиться к разбору кода по типу регулярных выражений... жадные операторы, нежадные операторы.
А то получается, что компиляторы явно не созрели до того что <> - это скобки...
В новый стандарт включили a>?
>> имел ввиду...
ОтветитьУдалитьВ новом стандарте ничего не поменялось в этом плане. Требование писать template осталось (см. draft n2857 14.3/4).
ОтветитьУдалить>> в новом стандарте можно писать в шаблонах. это, конечно, гораздо удобнее.
ОтветитьУдалитьЭто собственно две стороны одной медали... :)
ОтветитьУдалить>> компилятор воспринимает как сдвиг, хотя контекст для сдвига совершенно не уместен.
< компилятор воспринимает как меньше, вероятно на том основании, что справа стоит константа. И после этого выражение слева его конечно же не радует, в плане сравнения. :)
Однако С++ плохо приспособлен под шаблоны в их нынешнем виде. Я то думал, что только при использовании типа, определенного в шаблонном классе, нужен костыль в виде typename. А вот оказывается в функциях тоже нужен.
ОтветитьУдалитьСпасибо за информацию.