Ошибка шаблона g ++ или VC слишком либеральный? - PullRequest
0 голосов
/ 17 марта 2011

Я пишу сильно шаблонный кусок кода на C ++.Он отлично работал в VS 2005, но когда я пытаюсь скомпилировать его в g ++, я получаю некоторые действительно странные ошибки.

Необходимая часть кода (упрощенная до минимума, тоже не компилируется) выглядит следующим образом:

template <class Actual>
class Generic
{
public:
    typedef Actual ThisType;
};

template <class Actual>
class Intermediate : public Generic<Actual>
{
};

template <class Q>
class Derived : public Intermediate<Derived<Q> >
{
public:
    void FooBar()
    {
        ThisType q;
    }
};

Ошибка: «ThisType» не был объявлен в этой области »в строке, где объявляется« q ».

Любопытно, что все работает нормально, когда Derived не являетсяшаблон, но простой класс.Зачем компилятору искать реализацию функции шаблона еще до того, как он будет создан?Я знаю, что VC ++ слишком мало проверяет при компиляции шаблонов (неиспользуемые шаблоны могут даже содержать синтаксически некорректный код) - но не слишком ли много здесь проверяет g ++?Я попытался добавить ключевое слово typename без особой надежды, и это тоже не удалось.Есть ли способ заставить ThisType работать как положено?Я боюсь добавить его вручную в каждый производный класс - это громоздко, избыточно, не элегантно и приводит к ошибкам.

С уважением, MZ

Ответы [ 4 ]

4 голосов
/ 17 марта 2011

Безусловные имена не ищутся в зависимых базовых классах (ваш базовый класс зависит от параметра шаблона Q). Уточните это имя, и оно будет работать.

typename Derived::ThisType q;
1 голос
/ 17 марта 2011

Доверьтесь Онлайн-компилятору Comeau !

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 19: error: identifier "ThisType" is undefined
          ThisType q;
          ^

"ComeauTest.c", line 19: error: expected a ";" (perhaps on the previous statement)
          ThisType q;
                   ^

2 errors detected in the compilation of "ComeauTest.c".

Зависимые имена типов из унаследованных классов не учитываются, вы можете попытаться явно запросить ThisType:

typename Intermediate<Derived<Q> >::ThisType q;
0 голосов
/ 17 марта 2011

Код действительно плохо сформирован. Когда базовый класс зависит от параметра шаблона, он не учитывается при поиске по имени при поиске неквалифицированных имен.

В вашем случае безусловное имя ThisType не будет найдено в базовом классе Intermediate<Derived<Q> >, поскольку ваш базовый класс зависит от параметра шаблона Q.

0 голосов
/ 17 марта 2011

Вам не хватает имя_папки

template <class Actual> class Generic { public:
    typedef Actual ThisType; };

template <class Actual> class Intermediate : public Generic<Actual> { };

template <class Q> class Derived : public Intermediate<Derived<Q> > { public:
    void FooBar()
    {
        typename Derived::ThisType q;
        return *this;
    } };

int main(){}
...