Code:
#include <tr1/functional>
class Test
{
public:
Test() { ; }
virtual void foo() = 0;
};
void someFunc(Test& j)
{
j.foo();
}
void func(Test& j)
{
std::tr1::bind(someFunc, std::tr1::ref(j));
}
Using g++ 4.8.1 on Linux, compiling with --std=c++11
I get:
In file included from foo.cpp:1:0:
/usr/include/c++/4.8.1/tr1/functional: In instantiation of ‘class std::tr1::reference_wrapper<Test>’:
foo.cpp:17:44: required from here
/usr/include/c++/4.8.1/tr1/functional:495:9: error: cannot allocate an object of abstract type ‘Test’
operator()(_Args&... __args) const
^
foo.cpp:3:7: note: because the following virtual functions are pure within ‘Test’:
class Test
^
foo.cpp:7:18: note: virtual void Test::foo()
virtual void foo() = 0;
^
This doesn't seem to make any sense. Using the corresponding boost classes works fine. Can someone confirm this is a TR1 bug in G++ 4.8.1?
The libstdc++ tr1::reference_wrapper
implementation has this:
template<typename... _Args>
typename result_of<_M_func_type(_Args...)>::type
operator()(_Args&... __args) const
{
return __invoke(get(), __args...);
}
The result_of
expression uses a by-value _M_func_type
parameter (which is the template parameter of the reference_wrapper
i.e. Test
), so it tries to form the function type Test()
, which uses a by-value Test
return type, which is invalid for an incomplete or abstract type. I think I fixed this for std::reference_wrapper
ages ago, it needs to use result_of<_M_func_type&(Args...)>
.
The TR1 implementation in libstdc++ is not really maintained any longer - TR1 served its purpose but its time has passed.