наследование от класса специализированного Я? - PullRequest
4 голосов
/ 08 декабря 2011

Это действительный C ++?

template<class category>
class any_iterator : public any_iterator<void>
{ 
public:
        typedef any_iterator<void> any_iter_void;

        any_iterator() : any_iter_void() {}
};
template<>
class any_iterator<void>
{ 
public:
        typedef any_iterator<void> any_iter_void;

        any_iterator() {}
        void foo() {};
};

int main() {
    any_iterator<int> a;
    a.foo();
}

MSVC10 принимает его без ошибок / предупреждений на \WALL, но gcc-4.5.1 жалуется:

prog.cpp: 3: 5: ошибка: недопустимое использование неполного типа 'class any_iterator'
prog.cpp: 2: 11: ошибка: объявление 'class any_iterator'
prog.cpp: в функции 'int main ()':
prog.cpp: 21: 11: ошибка: в классе any_iterator нет члена с именем foo
prog.cpp: в конструкторе 'any_iterator :: any_iterator () [with category = int]':
prog.cpp: 20: 27: создается здесь
prog.cpp: 7: 44: ошибка: тип 'any_iterator' не является прямой базой для 'any_iterator'

Может ли кто-нибудь процитировать стандартный показ, если это должно или не должно компилироваться? Я думаю, что это ошибка в MSVC.

Как примечание, я знаю, что правильно сделать, это объявить класс, специализировать корень, затем определить общий случай, и это то, что я сделаю с моим кодом, но я был интересно, какой компилятор здесь не так?

Ответы [ 2 ]

4 голосов
/ 08 декабря 2011

Для наследования от типа этот тип должен быть завершенным. Небольшая перестановка решает вещи:

template<class category>
class any_iterator;

template<>
class any_iterator<void>
{ 
public:
    typedef any_iterator<void> any_iter_void;

    any_iterator() { }
    void foo() { }
};

template<class category>
class any_iterator : public any_iterator<void>
{ 
public:
    typedef any_iterator<void> any_iter_void;

    any_iterator() : any_iter_void() { }
};

int main()
{
    any_iterator<int> a;
    a.foo();
}

Стандартные кавычки токена:

C ++ 11, §10 / 2:

Тип, обозначаемый спецификатором базового типа , должен быть типом класса, который не является не полностью определенным классом; этот класс называется прямым базовым классом для определяемого класса.

§9.2 / 2:

Класс считается полностью определенным типом объекта (или полным типом) при закрытии } спецификатора класса .

0 голосов
/ 08 декабря 2011

10/2:

Тип, обозначаемый спецификатором базового типа, должен быть типом класса, который не является полностью определенным классом

Это одно из проявлений ошибки в MSVC: отсутствие разрешения двухфазного имени.

...