Код:
#include <functional>
struct Foo
{
virtual void mf() = 0;
};
struct Bar: Foo
{
virtual void mf() {}
};
int main()
{
Bar o;
std::reference_wrapper<Foo const> wrapper( o );
}
Результат с MinGW g++ 4.6.1:
[d:\dev\test] > g++ foo.cpp -std=c++0x [d:\dev\test] > _
Результат с Visual C++ 10.0:
[d:\dev\test] > cl foo.cpp foo.cpp C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно инстанцировать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xrefwrap(371) : см. ссылку на инстанцию шаблона класса 'std::tr1::_Call_wrapper' при компиляции с [ _Callable=std::tr1::_Callable_obj ] C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xrefwrap(416) : смотрите ссылку на инстанцию шаблона класса 'std::tr1::_Refwrap_impl', компилируемую с [ _Ty=const Foo ] foo.cpp(16) : смотрите ссылку на инстанцию шаблона класса 'std::tr1::reference_wrapper' в процессе компиляции с [ _Ty=const Foo ] C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2027: использование неопределенного типа 'std:: tr1::_Result_of' с [ _Ty=const Foo (void) ] C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(9) : error C2143: syntax error: missing ';' before '(' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(9) : ошибка C4430: отсутствует спецификатор типа - предполагается int. Примечание: C++ не поддерживает default-int C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(10) : ошибка C4430: отсутствует спецификатор типа - предполагается int. Примечание: C++ не поддерживает default-int C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно инстанцировать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xxcallwrap(8) : ошибка C2259: 'Foo': невозможно создать абстрактный класс из-за следующих членов: 'void Foo::mf(void)' : является абстрактным foo.cpp(5) : см. объявление 'Foo::mf' [d:\dev\test] > _
Мне нравится, что компилятор Visual C++ 11 раз сообщает пользователю, что абстрактный класс не может быть инстанцирован, просто чтобы вбить эту мысль в голову, типа, на случай, если пользователь не знал об этом. Но должен ли std::reference_wrapper
действительно инстанцировать класс? Разве смысл (передачи по) ссылке не в том, чтобы не требовать инстанцирования?
То есть, как я сильно подозреваю, это ошибка в реализации стандартной библиотеки Visual C++?