I am using the pimpl idiom and want to reference one of the methods of the forward declared class. Below isn’t exactly what I’m doing but uses the same concepts.
template< typename Class, void (Class::*Method)(void) > struct Call { Call( Class* c ) : m_c(c) { } void operator()( void ) { (m_c->*Method)(); } Class* m_c; }; class A { public: void foo( void ) { std::cout << 'A::foo\n'; } }; // this works void do_foo( A* a ) { Call<A,&A::foo> c(a); c(); } class B; // this doesn't compile extern void B::bar( void ); // this is what i'd ultimately like to do void do_bar( B* b ) { Call<B,&B::bar> c(b); c(); }
Two questions:
- Can this be done?
- Why can’t it be done?
You cannot forward declare a member function. I think the reason is that, when you call the function on a pointer to B, the compiler has to pass the this pointer to that method. But it doesn’t know the precise class hierarchy of B yet. So possible adjustments of that pointer (due to the method being virtual, for example) would not be possible at that point. The compiler would also not know what visibility that method has. After all, it could be private and you are not allowed to call it from outside. The only way to declare that member function is to define the class, and then declare the function within that definition. Another way to solve your problem is to declare your free function instead:
Then define do_bar in a file in which you can safely include the definition of the class B.