Error with std::bind and templated member functions - c++

I am currently writing a gameboy emulator for practicing C++. I have gotten to the part where I implement CPU instructions and decided a vector of std::function was a good choice.
Please note: u8 is an alias for uint8_t.
In my code, there is a vector of std::function<u8()> with three types of members:
A lambda expression that returns u8.
Pointer to a member function.
Pointer to a templated member function.
I tried to use an initalizer list at first, but it didn't work. I later found out that is because I needed a call to std::bind(/*function ptr*/, this); on the pointers, but when calling this on the templated function pointers, I get the following error: no matching function for call to 'bind'. I would like to have an initalizer list, as right now it is a function with successive calls to emplace_back.
Here is the erroring line:
instruction_set.emplace_back(bind(&CPU::OPLoadDualRegister8<B, B>, this)); // 0x40 LD B, B
One interesting thing is that when B is replaced with a literal (e.g. 0x00) it works perfectly. B is a u8 and that is what the template accepts.
So:
Is there any way I can do this less convoluted? (e.g. init lists, std::function with member function ptrs, etc.)
If this is the best way, what do I do about the templated ptrs?
Would it better if I took the template params as args and used std::bind to resolve them (all params are either u8 or u8&.
Any optimization suggestions?
Thanks, Zach.

Okay, there is a lot going on here between your question and the comments. Here are some things I notice right off the bat:
If you are going to index into a vector to decode op codes, you probably shouldn't just emplace_back into the vector in order. Instead grow the vector to its final size, filling it with null values and use the subscript operator to put the functions in. instruction_set[0x40] = ...
Using a switch statement and just calling the functions directly is likely a way better choice. Obviously, don't know the ins and outs of your project, so this may not be possible.
When you say B is u8 do you mean B is variable of type u8? Plain 'ol variables can't be used to instantiate templates. B would have to be a macro, template parameter on the calling function, constexpr variable, or static const (basically known at compile time).
std::bind is never any fun for anyone to use, so you are not alone. I don't think it is the root cause of your issue here, but you should probably prefer binding things using capturing lambdas.
Funnily enough C++'s new hearthrob Matt Godbolt (author of Compiler Explorer) gave a talk on emulating a 6502 in JavaScript last year. It's not exactly an authoritative reference on the subject, but it may be worth a watch if you are interested in emulating old microprocessors.

Related

Is storing any type of function in one variable possible?

I'm trying to make a menu array where each element is a struct that stores variables for text, key that needs to be pressed to select that item and function called on that key press (something like "Quit", 'Q', Quit()). I thought this would make things more efficient, but I can't find a way to make it work with varied function and parameter types (for example one item should be able to call a void function with no parameters, another a class int function with two parameters and so on). Is there a good way to do this or am I better off giving up on the idea?
Edit: Thank you all for your advice! The proposed solutions feel a little too complex for my newbie self, but attempting to understand them gave me some ideas! I ended up making the third variable hold an enum instead of a direct function call and then created a switch function that calls other functions based on that value.
There are actually a few ways of doing this.
One way is to use std::bind to bind all functions to void func(void) then you can store them equally.
The other way is to create a generic function/lambda which will call your function.
To store your functions you can use std::function.
Also consider overriding operator() of your classes.
The classic way of handling this is to have all the functions take the same parameters, and for those to be very flexible. For example, an integer or enum, and a pointer.
your no-parameter function is passed -1 and nullptr and ignores them
your multi-parameter function casts the pointer to a pointer to some struct or class that holds all the bits and pieces it needs (and of course your calling code made that instance and passed its address)
The reason an enum or integer is hoisted out as one of the parameters is that "command type" is a super popular thing to need, so why do all that casting and extracting to get it?
If you have a performance problem as a result of this approach, then there are others, but this has literally been used for decades in Windows.

Expression-local variable

I have tried to come up (just as an experiment, nothing serious) with a macro that wraps alloca in a more object-oriented way, using special "constructor" that returns the size the instance will need together with a pointer to a function that should initialize it.
Writing that using more statements is simple:
void (*initf)(Type *inst);
Type *obj = alloca(Type::init(&initf, ...));
initf(obj);
Obviously, wrapping that in a function would work if it was something else than alloca, but this needs to be inline.
Is it possible to make an expression that performs this kind of task, returning obj as its result? The design doesn't have to stay the same, but generally, there should be a function taking the arguments a constructor should take and produce the size and initializer function. If alloca took as a parameter std::pair<size_t,void(*)(void *ptr)>, it would all be much easier.
I suspect it may not be achieavable in C++, but just for curiosity, could it be done in C? It seems many features intended for macros were added lately.

C++: Creating a function object with mem_fn and bind1st

Disclaimer: This description contains a lot of Qt specific functionality. This is not necessary to answer the question, I'm just including it to explain the background.
I need to do some heavy computations in my QT application.
In order to do this, I would like to use QtConcurrent::run(myFunction) This is Qt's version of async and creates a future, which at some point will contain the result of myFunction.
The problem is that the function is both a member function and takes complex parameters.
I know that you can pass both a function and a pointer to QtConcurrent::run. The function will then be invoked on the pointer. You can even provide a list of parameters. But it seems like this list only accepts parameters such as int, double or QString.
Actual Question:
I would like to convert this line of code:
model->nextStep(simulatedResult->last().molecules, dt)
into
myFunction()
That means I need to
bind the pointer to the function
bind the arguments to the function
This is my code so far:
auto memfun=std::mem_fn(&ConcreteModel::nextStep);
auto memfun_bound_to_model=std::bind1st(memfun,model);
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules);
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt);
Unfortunately this doesn't work.
There are 18 compiler errors, here is the pastebin: http://pastebin.com/2rBQgFNL
It would be great, if you could explain how to do this properly.
Not necessary for an answer, but even better, would be code for QtConcurrent::run.
Simply use a lambda expression.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
You could also use std::bind (see #JonathanWakely's answer), but lamda expressions are imho more universal and powerful.
Also, keep in mind that reading and writing to the same memory from multiple threads will result in a data race (don't pass pointers/references to mutable data to the QT threads unless synchronization is used).
You're trying to mix the C++98 bind1st with the C++11 mem_fn, which isn't possible.
bind1st requires an adaptable binary function which means one that defines certain typedefs, and one that takes exactly two arguments. You can't use it with something that requires more than two and keep binding one argument at a time.
In C++11 it is possible to wrap function objects without those typedefs, thanks to decltype and other new features, so "adaptable binary function" is a useless concept now, and bind1st is useless and deprecated.
The solution is simply to use C++11 features instead of bind1st, e.g. std::bind or a lambda expression.
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);

Reflexion Perfect Forwarding and the Visitor Pattern

http://codepad.org/etWqYnn3
I'm working on some form of a reflexion system for C++ despite the many who have warned against. What I'm looking at having is a set of interfaces IScope, IType, IMember, IMonikerClient and a wrapper class which contains the above say CReflexion. Ignoring all but the member which is the important part here is what I would like to do:
1) Instance the wrapper
2) Determine which type is to be used
3) Instance type
4) Overload the () and [] to access the contained member from outer(the wrapper) in code as easily as it is done when using a std::vector
I find that using 0x I can forward a method call with any type for a parameter. I can't however cast dynamically as cast doesn't take a variable(unless there are ways I am unaware of!)
I linked the rough idea above. I am currently using a switch statement to handle the varying interfaces. I would, and for obvious reasons, like to collapse this. I get type match errors in the switch cases as a cause of the call to the methods compiling against each case where only one of three work for any condition and compiler errors are thrown.
Could someone suggest anything to me here? That is aside from sticking to VARIANT :/
Thanks!
C++, even in "0x land", simply does not expose the kind of information you would need to create something like reflection.
I find that using 0x I can forward a method call with any type for a parameter.
You cannot forward a type as a parameter. You can forward the const-volatile qualifiers on a member, but that's all done in templates, at compile time. No runtime check ever is done when you're using things like forward.
Your template there for operator() is not going to compile unless T is convertable to int*, string*, and A** all at once. Think of templates as a simple find and replace algorithm that generates several functions for you -- the value of T gets replaced with the typename when the template is instantiated, and the function is compiled as normal.
Finally, you can only use dyanmic_cast to cast down the class hierarchy -- casting between the completely unrelated types A B and C isn't going to operate correctly.
You're better off taking the time to rethink your design such that it doesn't use reflection at all. It will probably be a better design anyway, considering even in language with reflection, reflection is most often used to paper over poor designs.

(Obj) C++: Instantiate (reference to) class from template, access its members?

I'm trying to fix something in some Objective C++ (?!) code. I don't know either of those languages, or any of the relevant APIs or the codebase, so I'm getting stymied left and right.
Say I have:
Vector<char, sizeof 'a'>& sourceData();
sourceData->append('f');
When i try to compile that, I get:
error: request for member 'append' in 'WebCore::sourceData', which is of non-class type 'WTF::Vector<char, 1ul >& ()();
In this case, Vector is WTF::Vector (from WebKit or KDE or something), not STD::Vector. append() very much is supposed to be a member of class generated from this template, as seen in this documentation. It's a Vector. It takes the type the template is templated on.
Now, because I never write programs in Real Man's programming languages, I'm hella confused about the notations for references and pointers and dereferences and where we need them.
I ultimately want a Vector reference, because I want to pass it to another function with the signature:
void foobar(const Vector<char>& in, Vector<char>& out)
I'm guessing the const in the foobar() sig is something I can ignore, meaning 'dont worry, this won't be mangled if you pass it in here'.
I've also tried using .append rather than -> because isn't one of the things of C++ references that you can treat them more like they aren't pointers? Either way, its the same error.
I can't quite follow the error message: it makes it sound like sourceData is of type WTF:Vector<char, 1ul>&, which is what I want. It also looks from the those docs of WTF::Vector that when you make a Vector of something, you get an .append(). But I'm not familiar with templates, either, so I can't really tell i I'm reading that right.
EDIT:
(This is a long followup to Pavel Minaev)
WOW THANKS PROBLEM SOLVED!
I was actually just writing an edit to this post that I semi-figured out your first point after coming across a reference on the web that that line tells the compiler your forward declaring a func called sourceData() that takes no params and returns a Vector of chars. so a "non-class type" in this case means a type that is not an instance of a class. I interpreted that as meaning that the type was not a 'klass', i.e. the type of thing you would expect you could call like .addMethod(functionPointer).
Thanks though! Doing what you suggest makes this work I think. Somehow, I'd gotten it into my head (idk from where) that because the func sig was vector&, I needed to declare those as &'s. Like a stack vs. heap pass issue.
Anyway, that was my REAL problem, because I tried what you'd suggested about but that doesn't initialize the reference. You need to explicitly call the constructor, but then when I put anything in the constructor's args to disambiguate from being a forward decl, it failed with some other error about 'temporary's.
So in a sense, I still don't understand what is going on here fully, but I thank you heartily for fixing my problem. if anyone wants to supply some additional elucidation for the benefit of me and future google people, that would be great.
This:
Vector<char, sizeof 'a'>& sourceData();
has declared a global function which takes no arguments and returns a reference to Vector. The name sourceData is therefore of function type. When you try to access a member of that, it rightfully complains that it's not a class/struct/union, and operator-> is simply inapplicable.
To create an object instead, you should omit the parentheses (they are only required when you have any arguments to pass to the constructor, and must be omitted if there are none):
Vector<char, sizeof 'a'> sourceData;
Then you can call append:
sourceData.append('f');
Note that dot is used rather than -> because you have an object, not a pointer to object.
You do not need to do anything special to pass sourceData to a function that wants a Vector&. Just pass the variable - it will be passed by reference automatically:
foobar(sourceData, targetData);
Dipping your toes in C++ is never much fun. In this case, you've run into a couple of classic mistakes. First, you want to create an instance of Vector on the stack. In this case the empty () is interpreted instead as a declaratiton of a function called sourceData that takes no agruments and returns a reference to a Vector. The compiler is complaining that the resulting function is not a class (it's not). To create an instance of Vector instead, declare the instance without the () and remove the &. The parentheses are only required if you are passing arguments to the instance constructor and must be omitted if there are no arguments.
You want
Vector<char, sizeof 'a'> sourceData;
sourceData.append('f');
Vector<char, sizeof 'a'> outData; //if outData is not instantiated already
foobar(sourceData, outData);
This Wikipedia article gives a decent introduction to C++ references.