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!
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).
Related
class A is under test, I want EXPECT_CALL to to return immediately, and invoke lamda function with value 200(rvalue reference) for mocked asyncfunc() method. Please read the comments in line with the code
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include<iostream>
using namespace std;
// Concrete class
class B
{
public:
// asyncfunc signature, p2 is function pointer with argument as rvalue referrence
bool asyncfunc(int p1, std::function<void(int &&v)> &&p2, float p3){
cout << "asyncfunc() \n" << "param1 : " << p1 << "\nparam 3 : " << p3 << endl;
p2(100);
}
};
class MockB
{
public:
// asyncfunc mocked
MOCK_METHOD3(asyncfunc, bool (int, std::function<void(int &&v)> &&, float));
};
// unit under test - A
template< typename T>
class A
{
T *bobj;
void sync(){}
public:
A(T *pbobj):bobj(pbobj){}
void test_function()
{
bool value = bobj->asyncfunc(10, [this](int &&a){
cout << "Lamba : " << a << endl;
if(a == 100)
{
sync();
}
},
20);
cout << "test_function : " << value << endl;
}
};
// My tests look like below, I get compilation error
TEST(A, test_function)
{
MockB b;
A<MockB> obj(&b);
using namespace ::testing;
EXPECT_CALL(b, asyncfunc(_,_,_)).WillOnce(DoAll(InvokeArgument<1>(100),Return(true)));
obj.test_function();
}
I'm not 100% sure as you code snippet doesn't specify if the lambda returns something or not - please follow 'minimal, reproducible example' principle, but I think the problem might be that lambda returns no type (void) and your mock function asyncfunc returns non-void type (e.g. bool). In this case, you need to specify what shall be returned by the call to asyncfunc by using Return action:
struct MockClass {
MOCK_METHOD3(asyncfunc, bool(bool, std::function<void(bool)>, int));
};
TEST(MockTest, CallLambda) {
MockClass m{};
auto param{false};
EXPECT_CALL(m, asyncfunc(_, _, _)).WillOnce(DoAll(InvokeArgument<1>(param), Return(false)));
ASSERT_FALSE(m.asyncfunc(
true, [](bool) {}, 42)); // ASSERT_FALSE because `Return` action specified `false`
}
without DoAll and Return actions, gmock tries to use result of InvokeArgument as the return value of asyncfunc which it can't, because it cannot use void as bool.
I have some example code shown below that calls a class member function from a static context without first creating a proper instance of the object to call on.
I know this code seems strange and I don't want to go into a whole lot of side tracks discussing the reasoning behind where it came from unless it becomes relevant to answering the question.
My questions are:
Is the code below "correctly formed" according to the C++ spec?
If it is not correctly formed, then in what circumstances could I
expect this code to not work as expected (see sample output for an
example of expected outcome)?
I believe the following are some limitations with this:
Referencing "members" from a virtual base may cause undefined behavior
Actually making use of the "members" when called statically may cause
undefined behavior
The key thing to look at with regards to this question is the function: StaticCall(). Note that when calling using StaticCall(), I expect that none of the members will actually be used. It is primarily to enumerate type information about the available members without implementing a nearly duplicate second function.
Sample code:
#include <vector>
#include <string>
#include <iostream>
class Serializer;
template <typename ClassT> void StaticCall(Serializer& s)
{
// First create aligned storage for a "fake" this pointer for the member function call
//
// This allows us to de-reference obj and access addresses of members so long as we
// don't actually try and use the members as they are pointing to uninitialized memory
typename std::aligned_storage<sizeof(ClassT), __alignof(ClassT)>::type data;
ClassT* fake_obj = static_cast<ClassT*>(static_cast<void*>(&data));
fake_obj->ClassT::Serialize(s);
}
template <typename ClassT> void VirtualCall(ClassT& obj, Serializer& s)
{
obj.Serialize(s);
}
template <typename ClassT> void MemberCall(ClassT& obj, Serializer& s)
{
obj.ClassT::Serialize(s);
}
class Serializer
{
public:
enum Mode
{
MODE_STRUCTURE
, MODE_CONTENT
} mode;
template <typename TypeT> void DisplayStructure()
{
mode = MODE_STRUCTURE;
StaticCall<TypeT>(*this);
}
template <typename TypeT> void DisplayContentVirtual(TypeT& obj)
{
mode = MODE_CONTENT;
VirtualCall(obj, *this);
}
template <typename ThisT> void Type(ThisT* obj, const char* obj_name)
{
std::cerr << "Type: " << obj_name << std::endl;
}
template <typename ParentT, typename ThisT> void TypeWithBase(ThisT* obj, const char* obj_name)
{
std::cerr << "Parent ";
if (mode == MODE_STRUCTURE)
StaticCall<ParentT>(*this);
else if (mode == MODE_CONTENT)
MemberCall(static_cast<ParentT&>(*obj), *this);
std::cerr << "Type: " << obj_name << std::endl;
}
template <typename MemberT> void Member(MemberT& member, const char* member_name)
{
std::cerr << "Member: " << member_name;
if (mode == MODE_CONTENT)
std::cerr << " : " << member;
std::cerr << std::endl;
}
};
// Example usage
class Parent
{
public:
Parent(int i) : pmem_int(i), pmem_str("Hello") {}
virtual void Serialize(Serializer& s)
{
s.Type(this, "Parent");
s.Member(pmem_int, "pmem_int");
s.Member(pmem_str, "pmem_str");
}
virtual void Thing() = 0;
int pmem_int;
std::string pmem_str;
};
class Child : public Parent
{
public:
float cmem_float;
Child() : Parent(1234), cmem_float(334.0f) {}
virtual void Thing() {}
virtual void Serialize(Serializer& s)
{
s.TypeWithBase<Parent>(this, "Child");
s.Member(cmem_float, "cmem_float");
}
};
int main(int argc, char* argv[])
{
Serializer s;
std::cerr << "Parent structure: " << std::endl;
s.DisplayStructure<Parent>();
std::cerr << "\nChild structure: " << std::endl;
s.DisplayStructure<Child>();
Child c;
Parent* p = &c;
std::cerr << "\nContent: " << std::endl;
s.DisplayContentVirtual(*p);
return 0;
}
Expected output produced:
Parent structure:
Type: Parent
Member: pmem_int
Member: pmem_str
Child structure:
Parent Type: Parent
Member: pmem_int
Member: pmem_str
Type: Child
Member: cmem_float
Content:
Parent Type: Parent
Member: pmem_int : 1234
Member: pmem_str : Hello
Type: Child
Member: cmem_float : 334
Your StaticCall has undefined behavior (ยง9.3.1 [class.mfct.non-static]/p2):
If a non-static member function of a class X is called for an object
that is not of type X, or of a type derived from X, the behavior
is undefined.
data is pure storage; it's neither an object of type ClassT nor an object of a type derived from ClassT. It doesn't matter whether your non-static member function actually uses a member of that class. You are in UB land as soon as you make the call.
Consider following programme
#include <iostream>
#include <typeinfo>
template <class T>
void Output(const char * Str, T Func)
{
void *Ptr = reinterpret_cast<void *>(Func);
std::ptrdiff_t Num = reinterpret_cast<std::ptrdiff_t>(Ptr);
std::cout << Str << " " << Num << std::endl;
}
class TAnotherBase { long a[10]; };
struct TBase {
typedef void (TBase::*TFunc)();
TFunc Func;
TBase(TFunc F) {
Func = F;
Output("Ctor TBase ", Func);
}
void CallF() {
std::cout << "This in TBase: " << typeid(this).name() << " " << this << std::endl;
(this->*Func)();
}
};
struct TDerived: public TAnotherBase, public TBase {
TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) {
Output("Ctor TDerived ", &TDerived::F);
CallF();
}
void F() {
std::cout << "This in TDerived::F: " <<typeid(this).name() << " " << this << std::endl;
}
};
int main(int argc, char **argv) {
TDerived Derived;
return 0;
}
It generates this output:
Ctor TBase 4197502 (1)
Ctor TDerived 4197502 (2)
This in base: P5TBase 0x7fff6b30fc00 (3)
This in TDerived::F: P8TDerived 0x7fff6b30fbb0 (4)
What is going on here
I have function F in TDerived class, then I send pointer to the function to TBase class: TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) { and (1) output function pointer.
Then I output function pointer in TDerived class (2) and make TBase class to call the function: `CallF(); (4), (5).
TAnotherBase is here to make different this pointers of TBase and TDerived classes.
So, first question.
I read that function pointers is more like offsets relative to this. If so, why I get the same function pointer values in (1) and (2) - 4197502 ?
Second question
I output this in CallF function (3) and it is all right. But then I call function (this->*Func)(); via this (which is TBase) and in function F this magically becomes completely different this (4)! It changes its type and value! How it is possible? How compiler still remembers that Func (which type is typedef void (TBase::*TFunc)();) is actually from TDerived class? How compiler knows that it should adjust this before sending it to F? Why and how it works?
An example of one way this can be done is described in the Itanium ABI - if you're interested in how the C++ class model can be implemented I highly recommend reading that whole document.
When you convert from a pointer-to-derived-member-function to pointer-to-base-member-function the compiler knows that when you call it this will point to base not derived. So it needs to make sure that the first thing it does is to modify this back from base* to derived*. It can either do this by inventing a shim function which modifies this and jumps to the real function, or by just storing the offset along with the pointer and using it at the call site (which is what the reference above describes). Or I'm sure there are other ways.
(static_cast is not just a compile time operation; quite often it has to do real work at runtime.)
I am trying to pass a member of class as argument to a function (not member method). The simple example of my intention would be like this.
template <typename ObjType>
void myOutput(ObjType* obj, ????)
{
std::cout << obj->???? << std::endl;
}
struct A
{
int a;
};
struct B
{
std::string b;
};
int main()
{
A A1;
B B1;
A1.a = 1;
B1.b = "something";
myOutput(&A1, A1::a);
myOutput(&B1, B1::b);
return 0;
}
So my question is what should i replace "????" with? I am not using C++11.
Thanks.
EDIT:
To clarify my intentions. The function myOutput doesn't really know the name of my member, and i do not want to use a function like memberToString() or something.
So the output should look like this for first call.
void myOutput(A* obj, ????)
{
std::cout << obj->a << std::endl;
}
and for the second
void myOutput(B* obj, ????)
{
std::cout << obj->b << std::endl;
}
If you know the member name at compile time, you can use a member pointer to refer to the member.
template <typename ObjType, typename MembType>
void myOutput(ObjType* obj, MembType memb)
{
std::cout << obj->*memb << std::endl;
}
This can then be called as such:
myOutput(&A1, &A::a);
myOutput(&B1, &B::b);
Naturally, you should ask yourself why it is you want to do this, and if it wouldn't be possible to simply pass A1->a or B1->b directly into the function as a single argument, instead.
I'm trying to add a simple messaging system to my project, where events can be invoked by a function, which will lead to all callbacks registered to that event being called.
Now, the logical way to do this is using function pointers. It would be easily possible to pass the pointer to the desired callback function to the events manager, for registering. An event callback function would always return an int and take a void* as argument.
However I don't want to register static global functions as my event callbacks - I'd like to do it with class member functions.
Is it even possible to accomplish this with C++? Storing and calling pointers to member functions of different classes but with the same function header.
If this is not possible, do you have any suggestions on how I could work around this? I'd really like to add event listeners directly to my classes.
Yes it is possible. C++0x has the function class that handles this, and as others have pointed out Boost has similar facilities.
You can also roll your own, but the syntax is not for the faint of heart:
#include <iostream>
class Callable
{
public:
virtual ~Callable() {}
virtual int operator() (void* args) = 0;
};
class CallableFreeFunction : public Callable
{
public:
CallableFreeFunction(int (*func)(void*)) : func_(func) {}
virtual int operator() (void* args) { return (*func_)(args); }
private:
int (*func_)(void*);
};
template <typename tClass>
class ClassMemberCallable : public Callable
{
public:
ClassMemberCallable(tClass* instance, int (tClass::*memberfunction)(void*)) : instance_(instance), memberfunc_(memberfunction) {}
virtual int operator() (void* args) { return (instance_->*memberfunc_)(args); }
private:
tClass* instance_;
int (tClass::*memberfunc_)(void*);
};
class Foo
{
public:
int derp(void* args)
{
std::cout << args << '\n';
return 2;
}
};
int freefunctionfoo(void* args)
{
std::cout << "free" << args << '\n';
return 2;
}
int main(int argc, char* argv[])
{
Foo myfoo;
Callable* callable = new ClassMemberCallable<Foo>(&myfoo, &Foo::derp);
(*callable)(0);
delete callable;
callable = new CallableFreeFunction(freefunctionfoo);
(*callable)(0);
delete callable;
std::cin.get();
return 0;
}
This demonstrates a way of handling both free functions, and member functions in an opaque way. This is a simple example, and can be made more generic and robust in a number of ways. I'd refer you to these pages for syntax help:
http://www.newty.de/fpt/index.html
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
I'd also recommend looking at this for more ideas:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Of course it's possible ! Have a look at Boost.Signal2 and Boost.Bind.
Boost.Signal2 basically implements a signal and slots system which is exactly what you need.
Then, you can use boost::bind which is a generalization of std::bind1st and std::bind2nd to get function object wrappers to basically anything you can think of (in your case, member methods). It's really powerful.
See this official boost tutorial.
Here is my not-so-good attempt for doing a job like that:
First of all you need a base event handler class, well let's call it EvtHandler for now:
class Event; //implement this yourself, it shall contain general but good info about event
class EvtHandler
{
public:
virtual void handleEvent (Event & evt);
};
Then every class that is supposed to handle events in a way, should derive from this class, and they can implement new functions as much as they want as far as they return the same data type (void in this case) and recieve the same paramteres (Event in this case). Like this:
class Foo : public EvtHandler
{
public:
void handleFooEvent (Event & event);
};
Then I implemented message centers for each special event, which had to register listeners and dispatch events when needed:
class ShutdownMessageCenter
{
typedef std::map<EventHandler *, event_func> ListenerMap;
public:
void register (EvtHandler * handler, void(EvtHandler::*memFunc)(Event &)) {
m_lmap[handler] = memFunc;
}
void callListeners () {
Event shutdown_event (EM_SHUTDOWN /*just imagine this can mean something, idk*/);
ListenerMap::iterator itr = m_lmap.begin ();
for (; itr != m_lmap.end(); ++itr) {
EvtHandler * handler = itr->first;
void (EvtHandler::*func)(Event &) = itr->second;
(handler->*func)(shutdown_event);
}
}
private:
ListenerMap m_lmap;
};
Then you could register your EvtHandlers to this particular message center for example!
ShutdownMessageCenter message_center;
EvtHandler * some_handler = new EvtHandler ();
Foo * some_foo = new Foo ();
message_center.register (some_handler, &EvtHandler::handleEvent);
message_center.register (some_foo, static_cast<void (EvtHandler::*)(Event &)>(&Foo::handleFooEvent);
message_center.callListeners ();
But once again this is not good at all, just thought I would share! Sorry for the mess, haha!
I am not completely sure what you want to archive but maybe you should look at Boost Signals2
It is quite helpful if you want to create some sort of Signal/Slot mechanism.
No, it is not possible (unless you do c++/cli with .net).
Now, you can still create static functions, pass them an object as a parameter, and the only thing that they'll do is call your member function on that object. (Actually a cast will be required first).
The closest that I have managed is to register a static member function as the callback. The static member takes the object (this) pointer as an argument in addition to the arguments sent by the event handler and uses this to call the member function.
class myClass{
public:
static void callback(void *arg, void *obj)
{
if (obj)
reinterpret_cast<myClass*>(obj)->cb(arg);
}
private:
void cb(void *arg);
};
Register myClass::callback and this with your handler. You may need to wrap this in the structure that arg references if you are restricted in what can be returned.
I am using lukes answer with SWIG because SWIG does not support all C++11 features... This probably can be improved even further with Parsa Jamshidis approach.
I modified it to cover even more cases (variable amount of arguments and variable return type):
#include <iostream>
template <typename R, typename ...T>
class Callback
{
public:
virtual ~Callback() {}
virtual R operator() (T... args) = 0;
};
template <typename R, typename ...T>
class FreeCallback : public Callback<R, T...>
{
public:
FreeCallback(R(*func)(T...)) : func_(func) {}
virtual R operator() (T... args) { return (*func_)(args...); }
private:
R(*func_)(T...);
};
template <typename tClass, typename R, typename ...T>
class MemberCallback : public Callback<R, T...>
{
public:
MemberCallback(tClass* instance, R (tClass::*memberfunction)(T...)) : instance_(instance), memberfunc_(memberfunction) {}
virtual R operator() (T... args) { return (instance_->*memberfunc_)(args...); }
private:
tClass * instance_;
R (tClass::*memberfunc_)(T...);
};
class foo {
public:
Callback<int, int> *IntCallback;
Callback<int, int, double, double> *IntDoubleDoubleCallback;
};
class blub {
public:
int func1(int i) {
std::cout << "args: " << i << std::endl;
return 1;
}
int func2(int i, double d1, double d2){
std::cout << "args: " << i << " " << d1 << " " << d2 << std::endl;
return 0;
}
};
int freeFunc1(int i) {
std::cout << "args: " << i << std::endl;
return 1;
}
int freeFunc2(int i, double d1, double d2){
std::cout << "args: " << i << " " << d1 << " " << d2 << std::endl;
return 0;
}
int main() {
foo f;
blub b;
f.IntCallback = new MemberCallback<blub, int, int>(&b, &blub::func1);
f.IntDoubleDoubleCallback = new MemberCallback<blub, int, int, double, double>(&b, &blub::func2);
Callback<int, int> *IntFreeCallback = new FreeCallback<int, int>(&freeFunc1);
Callback<int, int, double, double> *IntDoubleDoubleFreeCallback = new FreeCallback<int, int, double, double>(&freeFunc2);
int ret = (*IntFreeCallback)(42);
std::cout << "ret freeFunc1: " << ret << std::endl;
ret = (*IntDoubleDoubleFreeCallback)(42, 3.1415, 2.7182);
std::cout << "ret freeFunc2: " << ret << std::endl;
ret = (*f.IntCallback)(42);
std::cout << "ret func1: " << ret << std::endl;
ret = (*f.IntDoubleDoubleCallback)(42, 3.1415, 2.7182);
std::cout << "ret func2: " << ret << std::endl;
std::cout << "Hello World!\n";
// cleanup not done here...
}