вторник, 22 декабря 2009 г.

Template keyword

Как вы думаете, что нужно написать, чтобы вызвать шаблонную фукнцию шаблонного класса из шаблонной фукнции?

Чтобы было понятно о чем идет речь, рассмотрим конкретный пример:
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()
{
A<TT> a;
a.template f<3>(); // correct
}
Слово template выглядит довольно неожиданно в этом месте, что приводит в замешательство не только новичков. Тем более, что Visual C++ игнорирует стандарт по непонятной причине. В будущем стандарте требование ключевого слова остается.

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.

6 комментариев:

  1. Мда, какой неожиданный изврат...

    Вероятно стоило бы относиться к разбору кода по типу регулярных выражений... жадные операторы, нежадные операторы.

    А то получается, что компиляторы явно не созрели до того что <> - это скобки...

    В новый стандарт включили a>?

    ОтветитьУдалить
  2. В новом стандарте ничего не поменялось в этом плане. Требование писать template осталось (см. draft n2857 14.3/4).

    ОтветитьУдалить
  3. >> в новом стандарте можно писать в шаблонах. это, конечно, гораздо удобнее.

    ОтветитьУдалить
  4. Это собственно две стороны одной медали... :)

    >> компилятор воспринимает как сдвиг, хотя контекст для сдвига совершенно не уместен.

    < компилятор воспринимает как меньше, вероятно на том основании, что справа стоит константа. И после этого выражение слева его конечно же не радует, в плане сравнения. :)

    ОтветитьУдалить
  5. Однако С++ плохо приспособлен под шаблоны в их нынешнем виде. Я то думал, что только при использовании типа, определенного в шаблонном классе, нужен костыль в виде typename. А вот оказывается в функциях тоже нужен.

    Спасибо за информацию.

    ОтветитьУдалить