Ошибка в компиляторе VC7
От: danikin  
Дата: 30.03.05 08:40
Оценка: 21 (1) +1

template <typename T>
class Base { virtual ~Base() {} };
template <typename T>
class Derived : public Base<T> { };

Base<int> *pb;

void f()
{
    cout << "f(): " << typeid(*pb).name() << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    pb = new Derived<int>;
    cout << "main(): " << typeid(*pb).name() << endl;
    f();
    cout << "main(): " << typeid(*pb).name() << endl;
    return 0;
}



Эта программа у меня выводит на экран следующее:

main(): class Derived<int>
f(): class Base<int>
main(): class Derived<int>

Причем, если после
Base<int> *pb;

поместить строчку,
template Base<int>;

то вывод уже правильный:

main(): class Derived<int>
f(): class Derived<int>
main(): class Derived<int>

Таким образом, компилятор не производит неявное инстанцирование Base<int>, хотя должен (см. стандарт (14.7.1): "... completeness of the class type affects the semantics of the program.")
Re: Ошибка в компиляторе VC7
От: Leshi Россия  
Дата: 30.03.05 09:06
Оценка:
Здравствуйте, danikin, Вы писали:

[skip]
Думаю, все-таки в pb лежит правильный объект (в смысле Derived<int>), а вот typeid косячит. Если на это не полагаться, тогда жить можно. Виртуальные функции вызываются как надо. В смысле
template <typename T>
class Base { public: virtual ~Base() {}; virtual void foo(){std::cout<<"--"<<std::endl;}; };
template <typename T>
class Derived : public Base<T> { public: virtual void foo(){std::cout<<"!!"<<std::endl;};};

Base<int> *pb;

void f()
{
    pb->foo();
    std::cout << "f(): " << typeid(*pb).name() << std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    pb = new Derived<int>;
    std::cout << "main(): " << typeid(*pb).name() << std::endl;
    f();
    std::cout << "main(): " << typeid(*pb).name() << std::endl;
    return 0;
}

Выдает:
main(): class Derived<int>
!!
f(): class Derived<int>
main(): class Derived<int>

Как ему и положено. Если вызов виртуальной функции грохнуть, тогда лажа. Думаю, все же это не совсем глюк. Что-то кажется было про typeid и виртуальные функции...
... << RSDN@Home 1.1.3 stable >>
Re: Ошибка в компиляторе VC7
От: VVV Россия  
Дата: 30.03.05 09:43
Оценка:
Здравствуйте, danikin, Вы писали:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_typeid_operator.asp


The expression must point to a polymorphic type (a class with virtual functions).

Re[2]: Ошибка в компиляторе VC7
От: Lorenzo_LAMAS  
Дата: 30.03.05 09:44
Оценка:
VVV>

VVV>The expression must point to a polymorphic type (a class with virtual functions).


А ты не заметил у автора в его коде наличия вируального деструктора?
Of course, the code must be complete enough to compile and link.
Re[2]: Ошибка в компиляторе VC7
От: _Winnie Россия C++.freerun
Дата: 30.03.05 09:44
Оценка:
Здравствуйте, VVV, Вы писали:

VVV>Здравствуйте, danikin, Вы писали:

VVV>

VVV>The expression must point to a polymorphic type (a class with virtual functions).

Ну вон там виртуальный деструктор наличествует.
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Ошибка в компиляторе VC7
От: Lorenzo_LAMAS  
Дата: 30.03.05 09:52
Оценка:
Вообще говоря, VC7 не единственный, кто глючит. icc 7.1 тоже выдает такой результат. gcc 3.3.3 работает, как ожидалось.
Of course, the code must be complete enough to compile and link.
Re: Ошибка в компиляторе VC7
От: Аноним  
Дата: 05.04.05 11:49
Оценка:
Ошибка, оказывается, не связана с шаблонами.

Например, такая программа
class Base;

void f(Base &b)
{
    cout << "f: " << typeid(b).name() << endl;
}

class Base
{
public:

    virtual void f() {}
};

class Derived : public Base
{
};

int _tmain(int argc, _TCHAR* argv[])
{
    Derived d;
    f(d);
    return 0;
}


выводит

f: class Base

Т.е. компилятор не требует определения класса Base при вызове typeid с операндом типа ссылка на Base.
В стандарте (3.2.4) сказано, что класс T должен быть определен, если вызывается typeid с операндом типа T. Однако, в данном случае вызывается typeid с операндом типа ссылка на T. Дает ли это право компилятору не требовать определения класса T?
Re[2]: Ошибка в компиляторе VC7
От: Lorenzo_LAMAS  
Дата: 05.04.05 11:57
Оценка:
А>В стандарте (3.2.4) сказано, что класс T должен быть определен, если вызывается typeid с операндом типа T. Однако, в данном случае вызывается typeid с операндом типа ссылка на T. Дает ли это право компилятору не требовать определения класса T?

Нет, не дает. В 5.2.8 в нескольких пунктах повторяется: shall be completely-defined.
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.