Pregunta

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?

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top