SFINAE? compiler bug?
От: Sergey Россия  
Дата: 24.09.07 11:47
Оценка:
Есть такой код:

#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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.