Reputation: 51
I came up with the following code when learning signal & slot, template, and function pointer.
Basically I am trying to make 2 classes, the base one will takes normal function pointers while the derived one will takes member function and wrap it up with a normal function, then pass it to the base class for invoking.
Here is the code:
#include<iostream>
struct foo {
void onNotify(int a, int b) {
std::cout << "member function: this=" << this << " a=" << a << " b=" << b << "\n";
}
};
void onNotify(void*, int a, int b) {
std::cout << "normal function: no context needed! a=" << a << " b=" << b << "\n";
}
// invoker that will takes normal functions.
template <typename...>
class invoker{
public:
invoker(void (*fptr)(void*, int, int), void* context){
fptr(context, 1, 2);
}
private:
invoker(){}
};
// invoker that will takes member functions.
template<class T>
class invoker<T> : public invoker<>{
public:
invoker<T>(T* context) : invoker<>(&forwarder, context){}
private:
invoker<T>(){}
static void forwarder(void* context, int i0, int i1) {
static_cast<T*>(context)->onNotify(i0, i1);
}
};
int main()
{
invoker<>(&onNotify, 0); // OK.
invoker<foo>(new foo); // OK.
invoker<foo>(0); // OK.
foo foo_;
auto f = invoker<foo>(&foo_); // OK.
// Errors:
// C2373 : 'foo_' : redefinition; different type modifiers.
// C2530 : 'foo_' : reference must be initialized.
invoker<foo>(&foo_); // ERROR!
return 0;
}
My questions are:
1) What is causing the compile error?
2) Why invoker<foo>(0);
will actually run without error?
Thanks in advance!
Upvotes: 1
Views: 123
Reputation: 55685
1) The problem is that
invoker<foo>(&foo_);
is parsed as a definition of variable foo_
that has type invoker<foo>&
rather than a call to the ctor of invoker<foo>
. There is a number of ways to fix this, for example, use extra parentheses:
(invoker<foo>)(&foo_);
2) The code
invoker<foo>(0);
compiles without an error because it's unambiguous (it can't be interpreted as a declaration).
Upvotes: 2