Есть такой код:
#include <vector>
class Bar
{
friend void TestOverload();
int x;
Bar(const Bar&);
Bar& operator=(const Bar&);
protected:
Bar() : x(0) {}
virtual ~Bar() = 0;
};
Bar::~Bar()
{}
struct BarC : Bar
{
~BarC() {}
};
template <class X> void foo(X &x, const std::vector<bool> &t)
{
;
}
template <class T> void foo(Bar &x, const std::vector<T> &t)
{
;
}
void foo(Bar &x, const std::vector<bool> &t)
{
foo<Bar>(x, t);
}
void Impl(Bar &x)
{
std::vector<bool> v;
foo(x, v);
}
void TestOverload()
{
BarC x;
Impl(x);
}
Оный код успешно компилируется Comeau online и не компилируется VC8 sp1:
1>c:\program files (x86)\microsoft visual studio 8\vc\include\vector(693) : error C2259: 'Bar' : cannot instantiate abstract class
1> due to following members:
1> 'Bar::~Bar(void)' : is abstract
1> c:\projects\testsoap\testsoap\testoverload.cpp(12) : see declaration of 'Bar::~Bar'
1> c:\projects\testsoap\testsoap\testoverload.cpp(35) : see reference to class template instantiation 'std::vector<_Ty,_Ax>' being compiled
1> with
1> [
1> _Ty=Bar,
1> _Ax=std::allocator<Bar>
1> ]
Т.е., очевидно, компилятор пытается инстанцировать template <class T> void foo(Bar &x, const std::vector<T> &t) для T==Bar, это, естественно, у него не получается, и тут вдруг вместо того, чтобы подставить template <class X> void foo(X &x, const std::vector<bool> &t) выдает ошибку компилляции. Если же лишить класс Bar чисто виртуальных функций, все странным образом собирается и работает, хотя vector<Bar> по прежнему не может быть инстанцирован — у Bar закрыты конструкторы и деструктор.
Собственно, вопросов два:
1) Я ничего не напутал и это действительно ошибка компилятора?
2) Как бы тут извратиться и все-таки суметь компилировать подобный код, с учетом того, что класс Bar и первый вариант функции foo (который template <class X> void foo(X &x, const std::vector<bool> &t) ) — сущности библиотечные и менять их крайне нежелательно.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.