auto type deduction coercion for templated class? - c++

I have 2 issues in a template class I'm building. I've included example code below. First question is whether I can coerce the auto type deducted for a templated class. i.e.:
auto p = myvar;
where myvar is T<...>, could I force auto to detect Q<...>? This is simplified. Read on for a more clear explanation.
Edited for clarity: Let me explain what I'm doing. And I'd also like to indicate that this style code is working on a large-scale project perfectly well. I am trying to add some features and functions and in addition to smooth out some of the more awkward behaviors.
The code uses templates to perform work on n-dimensional arrays. The template has a top-level class, and a storage class underneath. Passing the storage class into the top level class allows for a top level class which inherits the storage class. So I start with NDimVar, and I have NDimStor. I end up with
NDimVar<NDimStor>
The class contains NO DATA except for the buffer of data:
class NDimStor<size_t... dimensions> {
int buffer[Size<dimensions...>()]
}
This makes the address of the class == the address of the buffer. This is key to the whole implementation. Is this an incorrect assumption? (I can see this works on my system without any issues, but perhaps this isn't always the case.)
When I create NDimVar<NDimStor<10,10>> I end up with a 10x10 array.
I have functions for getting pieces of the array, for example:
NDimVar<NDimStor<dimensions...>>::RemoveDim & get(int index);
This creates a new 1d array of 10 elements out of the 2d 10x10 array:
NDimVar<NdimStor<10>>
In order to return this as a reference, I use a reinterpret_cast at the location of the data I want. So in this example, get(3) would perform:
return reinterpret_cast<NDimVar≤NDimStor<dimensions...>>::RemoveDim&>(buffer[index * DimensionSumBelow<0>()]);
DimensionSumBelow<0> returns the sum of elements at dimensions 1+, i.e. 10. So &buffer[30] is the address of the referenced 1d NDimVar.
All of this works very well.
The only issue I have is that I would like to add on overlays. For example, be able to return a reference to a new class:
NDimVar<NDimPermute<NDimStor<10,10>,1,0>>
that points to the same original location along with a permutation behavior (swapping dimensions). This also works well. But I would like for:
auto p = myvar.Permute<1,0>()
to create a new copy of myvar with permuted data. This would work if I said:
NDimVar<NDimStor<10,10>> p = myvar.Permute<1,0>().
I feel that there is some auto type deduction stuff I could do in order to coerce the auto type returned, but I'm not sure. I haven't been able to figure it out.
Thanks again,
Nachum
What I want is:
1. Create temporary overlay classes on my storage, e.g. A_top<A_storage> can return a type called A_top<A_overlay<A_storage>> without creating a new object, it just returns a reference to this type. This changes the way the storage is accessed. The problem is upon a call to auto. I don't want this type to be instantiated directly. Can I modify the return to auto to be an original A_top?
#include <iostream>
using namespace std;
class A_storage {
public:
float arr[10];
A_storage () {
}
float & el (int index) {
return arr[index];
}
};
template <typename T> class A_overlay : T {
private:
A_overlay () {
cout << "A_overlay ()" << endl;
}
A_overlay (const A_overlay &) {
cout << "A_overlay (&)" << endl;
}
public:
using T::arr;
float & el (int index) {
return arr[10 - index];
}
};
template <typename T> class A_top;
template <typename T> class A_top : public T {
public:
A_top () {
}
A_top<A_overlay<A_storage>> & get () {
return reinterpret_cast<A_top<A_overlay<A_storage>>&>(*this);
}
};
using A = A_top<A_storage>;
int main (void) {
A a;
auto c = a.get(); // illegal - can i auto type deduce to A_top<A_storage>?
return 0;
}
If a function accepts (A_top<A_storage> &) as a parameter, how can I create a conversion function that can cast A_top<A_overlay<A_storage>>& to A_top<A_storage>& ?
Thanks,
Nachum

First, your design doesn't look right to me, and I'm not sure if the behaviour is actually well-defined or not. (Probably not.)
In any case, the problem is not with auto. The error is caused by the fact that the copy constructor of A_overlay is private, while you need it to copy A_top<A_overlay<A_storage>> returned by a.get() to auto c.
(Note that the auto in this case obviously gets deduced to A_top<A_overlay<A_storage>>, I assume you made a typo when said that it's A_top<A_storage>.)
Also note that A_storage in A_top::get() should be replaced with T, even if it doesn't change anything in your snippet because you only have T == A_storage.
If a function accepts (A_top &) as a parameter, how can I create a conversion function that can cast A_top> to A_top& ?
Ehm, isn't it just this:
return reinterpret_cast<A_top<A_storage>&>(obj);

reinterpret_cast should almost never be used. It essentially remove any compiler validation that the types are related. And doing unrelated cast is essentially undefined behavior as it essentially assume that derived classes are always at offset 0...
It does not make any sense to write such code. It is not maintainable and hard to understand what you are trying to achieve. It look like you want to pretend that your A_top<A_storage> object is a A_top<A_overlay<A_storage>> object instead. If this is what you want to do, then declare A alias as that type.
In your code, it look like you want to invert the indexing so that item at position 10 is returned when you ask item at position 0 and vice versa. Do you really think, that it is obvious from your obfuscated code? Never write such bad code.
Something like
class A_overlay {
public:
float & el (int index) { return arr[10 - index]; }
private:
A_storage arr;
};
would make much more sense than your current code.
No cast needed.
Easy to understand.
Well defined behavior.
You might keep your job.
And obviously, you would update the following line as appropriate:
using A = A_top<A_storage>;
Also, if A_top has no useful purpose, then why not using A_overlay directly? And why are you using template if A_storage is not a template? Do you really want to reuse such mess elsewhere in your code base.
Obviously, your code inheritance does not respect IS-A relationship if your write such code. So it is clearly a bad design!

Related

What is a nice way to cycle through an enum?

Background
For a UI in an embedded project, I'm looking for a nice generic way to store a "state" and cycle through it with a button press, e.g. a list of menu items.
Normally, I like to use enums for this purpose, for example:
enum class MenuItem {
main,
config,
foo,
bar,
};
Then, in my UI code, I can store a currentMenuItem state like
MenuItem currentMenuItem = MenuItem::MAIN;
and do things depending on the current state by comparing currentMenuItem to any of its possible values, as declared in the enum.
Problem
The thing is, I would now like to advance to the next menu item. For that, I can quite trivially write a function that does that by casting to int, incrementing by one, and casting it back to the enum. I have multiple distinct enums, so I can even use this templated function that does this for arbitrary enums:
template <typename T>
void advanceEnum(T &e) {
e = static_cast<T>(static_cast<int>(e) + 1);
}
The problem with this is that it doesn't wrap around: it will happily keep increasing the underlying integer beyond the number of elements in the actual enum. I could quite easily solve this (by taking the modulo with the number of elements in the above function), if only there was an clean way to get the element count of an enum. Which, as far as I could find, there isn't really.
Custom enum?
I was thinking of writing a custom 'CyclicEnum' class that implements this behaviour, that I can subsequently derive from. That way, I could also write this as an overloaded operator++.
However, I still haven't devised how to can get an enum-like thing without actually using an enum. For example, I got to something like this:
class CyclicEnum {
public:
uint8_t v;
CyclicEnum& operator++() {
v = (v+1) % count;
return *this;
}
CyclicEnum operator++(int) {
CyclicEnum old = *this;
operator++();
return old;
}
private:
uint8_t count;
protected:
CyclicEnum(uint8_t v, uint8_t count) : v(v), count(count) {}
};
struct Tab : public CyclicEnum {
enum Value {
main,
config,
foo,
bar,
};
Tab(Value v) : CyclicEnum(v, 4) {}
};
However, as you can see, this still uses an enum inside the custom CyclicEnum class, and I'm back to the same issue: I can't count the number of Enum elements, so I have to specify that manually (which I think is not nice because it's redundant). Secondly, this way I also have to override the constructor in the derived class which I would like to avoid to keep it as clean as possible.
Upon searching this issue, many people apparently recommend to add a "dummy" value at the end of the enum as a trick to get the size:
enum Value {
main,
config,
foo,
bar,
_count,
};
but frankly, I find that just ugly, since _count is now actually a valid option.
Is there any way around this? Am I abusing enums? Looking at the fact that enums are apparently (by design) so hard to count, probably. But what would be a nice way to have a structure like this with named values like an enum provides?
EDIT:
OK, I'm convinced that using a _count element at the end isn't so bad of an idea. Still, I'd like to encapsulate this in some kind of structure, like a class.
I also thought of instead of using inheritance, using a class template to accomplish this, something like this:
(caution, this doesn't compile):
template<typename T>
struct CyclicEnum {
T v;
enum Values = T;
CyclicEnum& operator++() {
v = (v+1) % T::_count;
return *this;
}
CyclicEnum operator++(int) {
CyclicEnum old = *this;
operator++();
return old;
}
CyclicEnum(T v) : v(v) {}
};
struct MenuItem : public CyclicEnum<enum class {
main,
config,
foo,
bar,
_count,
}> {};
However, this does not work because "ISO C++ forbids forward references to 'enum' types" and "anonymous enum cannot be defined in a type specifier"...
Is there another way to make this idea work (template a class with an enum), or is this not going to work?
The thing is, I would now like to advance to the next menu item.
++ comes to mind. Keep it simple.
That way, I could also write this as an overloaded operator++
Yeah... or again, keep it simple, you could just drop the whole class. There's no need to write an abstraction layer around a simple integer. Really.
Upon searching this issue, many people apparently recommend to add a "dummy" value at the end of the enum as a trick to get the size
Sure why not. This is incredibly common practice.
but frankly, I find that just ugly, since LAST is now actually a valid option.
It's canonical code, it isn't ugly. Just give it a sensible name, maybe something like MENU_ITEMS_N to suggest that this a counter variable then use it as such. for(int i=0; i<MENU_ITEMS_N; i++) ...
Am I abusing enums?
Enums are just named integer values. Don't over-engineer your code. It's bad for performance, it's bad for maintenance, it adds needless complexity.
You could use the magic_enum library to reflect on enums.
Example which gets the names of all enum elements as std::array < std::string_view > and prints them.
#include <algorithm>
#include <iostream>
#include <magic_enum.hpp>
enum struct Apple
{
Fuji = 2,
Honeycrisp = -3,
Envy = 4
};
int
main ()
{
constexpr auto &appleNames = magic_enum::enum_names<Apple> (); // get an std::array<std::string_view> with the names for the enum sorted by value
std::copy (appleNames.begin (), appleNames.end (), std::ostream_iterator<std::string_view> (std::cout, "\n")); // print all the names
}
Prints:
Honeycrisp
Fuji
Envy
There are some limitations please read magic enum limitations
Rather then using _count, set the last "sentinel" value to the last actual value.
enum Value {
main,
config,
foo,
bar,
last = bar
};
Then you avoid the problem of having an enum value that is not a valid menu option. in your increment for example instead of :
v = static_cast<Value>( (static_cast<int>(v) + 1) %
static_cast<int>(Value::_count) );
you'd have:
v = static_cast<Value>( (static_cast<int>(v) + 1) %
(static_cast<int>(Value::last) + 1) ) ;
If in fact these enums simply cause different menu item handler functions to be called, then you could instead used an array of pointer-to-functions rather then an enum/switch or whatever.

Share a function across template instances

I would like to share a function across template instantiations, and wonder whether there's a way to do that.
_____ edit to clarify question _____
Lets look at the following example
#include <array>
template <unsigned int K>
class kd_tree
{
public:
using kd_point = std::array<float, K>;
bool isValid(const kd_point &kdPoint) const
{
for (unsigned i = 0; i < K; i++)
if ( isnan(kdPoint[i]) ||
kdPoint[i] == numeric_limits<float>::infinity() ||
kdPoint[i] == -numeric_limits<float>::infinity() )
return false;
return true;
}
};
for each value of K, a new value of isValid will be created that differs by nothing except the concrete value of K. It certainly doesn't need K to use kd_point's operator[]
Question is whether there's a way to take isValid out of the class and make it a function that accepts a kd_point & a K as parameters, and check the point, thus saving in executable size on multiple copies of it, e.g. one for K=2 & another for K=3.
I'm not sure I've understood the question, but could a factory like the following one solve the problem?
void fn() { }
template<void(*Function)()>
class C {
C() = default;
public:
static C<Function>* create() {
return new C<Function>{};
}
};
using CfnFactory = C<fn>;
int main() {
C<fn> *c = CfnFactory::create();
}
Note that the example above applies well also with member functions, it's only a minimal example of a possible solution from which to start (of course, if I got the problem).
The idea is to inject in the factory the function to be used to create instances of your type, so that all of them will rely on the same function. This way you can also create multiple factories based on different functions and mix together the returned objects (the last point requires a base, non-template class, but it's quite easy to do).
In any case, I strongly suggest you to reduce the amount of code in your example to a mvce.
It would help the reader and it will increase the chances to get a valid response.

What is the practical use of pointers to member functions?

I've read through this article, and what I take from it is that when you want to call a pointer to a member function, you need an instance (either a pointer to one or a stack-reference) and call it so:
(instance.*mem_func_ptr)(..)
or
(instance->*mem_func_ptr)(..)
My question is based on this: since you have the instance, why not call the member function directly, like so:
instance.mem_func(..) //or: instance->mem_func(..)
What is the rational/practical use of pointers to member functions?
[edit]
I'm playing with X-development & reached the stage where I am implementing widgets; the event-loop-thread for translating the X-events to my classes & widgets needs to start threads for each widget/window when an event for them arrives; to do this properly I thought I needed function-pointers to the event-handlers in my classes.
Not so: what I did discover was that I could do the same thing in a much clearer & neater way by simply using a virtual base class. No need whatsoever for pointers to member-functions. It was while developing the above that the doubt about the practical usability/meaning of pointers to member-functions arose.
The simple fact that you need a reference to an instance in order to use the member-function-pointer, obsoletes the need for one.
[edit - #sbi & others]
Here is a sample program to illustrate my point:
(Note specifically 'Handle_THREE()')
#include <iostream>
#include <string>
#include <map>
//-----------------------------------------------------------------------------
class Base
{
public:
~Base() {}
virtual void Handler(std::string sItem) = 0;
};
//-----------------------------------------------------------------------------
typedef void (Base::*memfunc)(std::string);
//-----------------------------------------------------------------------------
class Paper : public Base
{
public:
Paper() {}
~Paper() {}
virtual void Handler(std::string sItem) { std::cout << "Handling paper\n"; }
};
//-----------------------------------------------------------------------------
class Wood : public Base
{
public:
Wood() {}
~Wood() {}
virtual void Handler(std::string sItem) { std::cout << "Handling wood\n"; }
};
//-----------------------------------------------------------------------------
class Glass : public Base
{
public:
Glass() {}
~Glass() {}
virtual void Handler(std::string sItem) { std::cout << "Handling glass\n"; }
};
//-----------------------------------------------------------------------------
std::map< std::string, memfunc > handlers;
void AddHandler(std::string sItem, memfunc f) { handlers[sItem] = f; }
//-----------------------------------------------------------------------------
std::map< Base*, memfunc > available_ONE;
void AddAvailable_ONE(Base *p, memfunc f) { available_ONE[p] = f; }
//-----------------------------------------------------------------------------
std::map< std::string, Base* > available_TWO;
void AddAvailable_TWO(std::string sItem, Base *p) { available_TWO[sItem] = p; }
//-----------------------------------------------------------------------------
void Handle_ONE(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
std::map< Base*, memfunc >::iterator it;
Base *inst = NULL;
for (it=available_ONE.begin(); ((it != available_ONE.end()) && (inst==NULL)); it++)
{
if (it->second == f) inst = it->first;
}
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_TWO(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
Base *inst = available_TWO[sItem];
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_THREE(std::string sItem)
{
Base *inst = available_TWO[sItem];
if (inst) inst->Handler(sItem);
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
int main()
{
Paper p;
Wood w;
Glass g;
AddHandler("Paper", (memfunc)(&Paper::Handler));
AddHandler("Wood", (memfunc)(&Wood::Handler));
AddHandler("Glass", (memfunc)(&Glass::Handler));
AddAvailable_ONE(&p, (memfunc)(&Paper::Handler));
AddAvailable_ONE(&g, (memfunc)(&Glass::Handler));
AddAvailable_TWO("Paper", &p);
AddAvailable_TWO("Glass", &g);
std::cout << "\nONE: (bug due to member-function address being relative to instance address)\n";
Handle_ONE("Paper");
Handle_ONE("Wood");
Handle_ONE("Glass");
Handle_ONE("Iron");
std::cout << "\nTWO:\n";
Handle_TWO("Paper");
Handle_TWO("Wood");
Handle_TWO("Glass");
Handle_TWO("Iron");
std::cout << "\nTHREE:\n";
Handle_THREE("Paper");
Handle_THREE("Wood");
Handle_THREE("Glass");
Handle_THREE("Iron");
}
{edit] Potential problem with direct-call in above example:
In Handler_THREE() the name of the method must be hard-coded, forcing changes to be made anywhere that it is used, to apply any change to the method. Using a pointer to member-function the only additional change to be made is where the pointer is created.
[edit] Practical uses gleaned from the answers:
From answer by Chubsdad:
What: A dedicated 'Caller'-function is used to invoke the mem-func-ptr;Benefit: To protect code using function(s) provided by other objectsHow: If the particular function(s) are used in many places and the name and/or parameters change, then you only need to change the name where it is allocated as pointer, and adapt the call in the 'Caller'-function. (If the function is used as instance.function() then it must be changed everywhere.)
From answer by Matthew Flaschen:
What: Local specialization in a classBenefit: Makes the code much clearer,simpler and easier to use and maintainHow: Replaces code that would conventionally be implement using complex logic with (potentially) large switch()/if-then statements with direct pointers to the specialization; fairly similar to the 'Caller'-function above.
The same reason you use any function pointer: You can use arbitrary program logic to set the function pointer variable before calling it. You could use a switch, an if/else, pass it into a function, whatever.
EDIT:
The example in the question does show that you can sometimes use virtual functions as an alternative to pointers to member functions. This shouldn't be surprising, because there are usually multiple approaches in programming.
Here's an example of a case where virtual functions probably don't make sense. Like the code in the OP, this is meant to illustrate, not to be particularly realistic. It shows a class with public test functions. These use internal, private, functions. The internal functions can only be called after a setup, and a teardown must be called afterwards.
#include <iostream>
class MemberDemo;
typedef void (MemberDemo::*MemberDemoPtr)();
class MemberDemo
{
public:
void test1();
void test2();
private:
void test1_internal();
void test2_internal();
void do_with_setup_teardown(MemberDemoPtr p);
};
void MemberDemo::test1()
{
do_with_setup_teardown(&MemberDemo::test1_internal);
}
void MemberDemo::test2()
{
do_with_setup_teardown(&MemberDemo::test2_internal);
}
void MemberDemo::test1_internal()
{
std::cout << "Test1" << std::endl;
}
void MemberDemo::test2_internal()
{
std::cout << "Test2" << std::endl;
}
void MemberDemo::do_with_setup_teardown(MemberDemoPtr mem_ptr)
{
std::cout << "Setup" << std::endl;
(this->*mem_ptr)();
std::cout << "Teardown" << std::endl;
}
int main()
{
MemberDemo m;
m.test1();
m.test2();
}
My question is based on this: since you have the instance, why not call the member function directly[?]
Upfront: In more than 15 years of C++ programming, I have used members pointers maybe twice or thrice. With virtual functions being around, there's not all that much use for it.
You would use them if you want to call a certain member functions on an object (or many objects) and you have to decide which member function to call before you can find out for which object(s) to call it on. Here is an example of someone wanting to do this.
I find the real usefulness of pointers to member functions comes when you look at a higher level construct such as boost::bind(). This will let you wrap a function call as an object that can be bound to a specific object instance later on and then passed around as a copyable object. This is a really powerful idiom that allows for deferred callbacks, delegates and sophisticated predicate operations. See my previous post for some examples:
https://stackoverflow.com/questions/1596139/hidden-features-and-dark-corners-of-stl/1596626#1596626
Member functions, like many function pointers, act as callbacks. You could manage without them by creating some abstract class that calls your method, but this can be a lot of extra work.
One common use is algorithms. In std::for_each, we may want to call a member function of the class of each member of our collection. We also may want to call the member function of our own class on each member of the collection - the latter requires boost::bind to achieve, the former can be done with the STL mem_fun family of classes (if we don't have a collection of shared_ptr, in which case we need to boost::bind in this case too). We could also use a member function as a predicate in certain lookup or sort algorithms. (This removes our need to write a custom class that overloads operator() to call a member of our class, we just pass it in directly to boost::bind).
The other use, as I mentioned, are callbacks, often in event-driven code. When an operation has completed we want a method of our class called to handle the completion. This can often be wrapped into a boost::bind functor. In this case we have to be very careful to manage the lifetime of these objects correctly and their thread-safety (especially as it can be very hard to debug if something goes wrong). Still, it once again can save us from writing large amounts of "wrapper" code.
There are many practical uses. One that comes to my mind is as follows:
Assume a core function such as below (suitably defined myfoo and MFN)
void dosomething(myfoo &m, MFN f){ // m could also be passed by reference to
// const
m.*f();
}
Such a function in the presence of pointer to member functions, becomes open for extension and closed for modification (OCP)
Also refer to Safe bool idiom which smartly uses pointer to members.
The best use of pointers to member functions is to break dependencies.
Good example where pointer to member function is needed is Subscriber/Publisher pattern :
http://en.wikipedia.org/wiki/Publish/subscribe
In my opinion, member function pointers do are not terribly useful to the average programmer in their raw form. OTOH, constructs like ::std::tr1::function that wrap member function pointers together with a pointer to the object they're supposed to operate on are extremely useful.
Of course ::std::tr1::function is very complex. So I will give you a simple example that you wouldn't actually use in practice if you had ::std::tr1::function available:
// Button.hpp
#include <memory>
class Button {
public:
Button(/* stuff */) : hdlr_(0), myhandler_(false) { }
~Button() {
// stuff
if (myhandler_) {
delete hdlr_;
}
}
class PressedHandler {
public:
virtual ~PressedHandler() = 0;
virtual void buttonPushed(Button *button) = 0;
};
// ... lots of stuff
// This stores a pointer to the handler, but will not manage the
// storage. You are responsible for making sure the handler stays
// around as long as the Button object.
void setHandler(const PressedHandler &hdlr) {
hdlr_ = &hdlr;
myhandler_ = false;
}
// This stores a pointer to an object that Button does not manage. You
// are responsible for making sure this object stays around until Button
// goes away.
template <class T>
inline void setHandlerFunc(T &dest, void (T::*pushed)(Button *));
private:
const PressedHandler *hdlr_;
bool myhandler_;
template <class T>
class PressedHandlerT : public Button::PressedHandler {
public:
typedef void (T::*hdlrfuncptr_t)(Button *);
PressedHandlerT(T *ob, hdlrfuncptr_t hdlr) : ob_(ob), func_(hdlr) { }
virtual ~PressedHandlerT() {}
virtual void buttonPushed(Button *button) { (ob_->*func_)(button); }
private:
T * const ob_;
const hdlrfuncptr_t func_;
};
};
template <class T>
inline void Button::setHandlerFunc(T &dest, void (T::*pushed)(Button *))
{
PressedHandler *newhandler = new PressedHandlerT<T>(&dest, pushed);
if (myhandler_) {
delete hdlr_;
}
hdlr_ = newhandler;
myhandler_ = true;
}
// UseButton.cpp
#include "Button.hpp"
#include <memory>
class NoiseMaker {
public:
NoiseMaker();
void squee(Button *b);
void hiss(Button *b);
void boo(Button *b);
private:
typedef ::std::auto_ptr<Button> buttonptr_t;
const buttonptr_t squeebutton_, hissbutton_, boobutton_;
};
NoiseMaker::NoiseMaker()
: squeebutton_(new Button), hissbutton_(new Button), boobutton_(new Button)
{
squeebutton_->setHandlerFunc(*this, &NoiseMaker::squee);
hissbutton_->setHandlerFunc(*this, &NoiseMaker::hiss);
boobutton_->setHandlerFunc(*this, &NoiseMaker::boo);
}
Assuming Button is in a library and not alterable by you, I would enjoy seeing you implement that cleanly using a virtual base class without resorting to a switch or if else if construct somewhere.
The whole point of pointers of pointer-to-member function type is that they act as a run-time way to reference a specific method. When you use the "usual" syntax for method access
object.method();
pointer->method();
the method part is a fixed, compile-time specification of the method you want to call. It is hardcoded into your program. It can never change. But by using a pointer of pointer-to-member function type you can replace that fixed part with a variable, changeable at run-time specification of the method.
To better illustrate this, let me make the following simple analogy. Let's say you have an array
int a[100];
You can access its elements with fixed compile-time index
a[5]; a[8]; a[23];
In this case the specific indices are hardcoded into your program. But you can also access array's elements with a run-time index - an integer variable i
a[i];
the value of i is not fixed, it can change at run-time, thus allowing you to select different elements of the array at run-time. That is very similar to what pointers of pointer-to-member function type let you do.
The question you are asking ("since you have the instance, why not call the member function directly") can be translated into this array context. You are basically asking: "Why do we need a variable index access a[i], when we have direct compile-time constant access like a[1] and a[3]?" I hope you know the answer to this question and realize the value of run-time selection of specific array element.
The same applies to pointers of pointer-to-member function type: they, again, let you to perform run-time selection of a specific class method.
The use case is that you have several member methods with the same signature, and you want to build logic which one should be called under given circumstances. This can be helpful to implement state machine algorithms.
Not something you use everyday...
Imagine for a second you have a function that could call one of several different functions depending on parameters passed.
You could use a giant if/else if statement
You could use a switch statement
Or you could use a table of function pointers (a jump table)
If you have a lot of different options the jump table can be a much cleaner way of arranging your code ...
Its down to personal preference though. Switch statement and jump table correspond to more or less the same compiled code anyway :)
Member pointers + templates = pure win.
e.g. How to tell if class contains a certain member function in compile time
or
template<typename TContainer,
typename TProperty,
typename TElement = decltype(*Container().begin())>
TProperty grand_total(TContainer& items, TProperty (TElement::*property)() const)
{
TProperty accum = 0;
for( auto it = items.begin(), end = items.end(); it != end; ++it) {
accum += (it->*property)();
}
return accum;
}
auto ship_count = grand_total(invoice->lineItems, &LineItem::get_quantity);
auto sub_total = grand_total(invoice->lineItems, &LineItem::get_extended_total);
auto sales_tax = grand_total(invoice->lineItems, &LineItem::calculate_tax);
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
This is completely missing the point. There are two indepedent concerns here:
what action to take at some later point in time
what object to perform that action on
Having a reference to an instance satisfies the second requirement. Pointers to member functions address the first: they are a very direct way to record - at one point in a program's execution - which action should be taken at some later stage of execution, possibly by another part of the program.
EXAMPLE
Say you have a monkey that can kiss people or tickle them. At 6pm, your program should set the monkey loose, and knows whom the monkey should visit, but around 3pm your user will type in which action should be taken.
A beginner's approach
So, at 3pm you could set a variable "enum Action { Kiss, Tickle } action;", then at 6pm you could do something like "if (action == Kiss) monkey->kiss(person); else monkey->tickle(person)".
Issues
But that introducing an extra level of encoding (the Action type's introduced to support this - built in types could be used but would be more error prone and less inherently meaningful). Then - after having worked out what action should be taken at 3pm, at 6pm you have to redundantly consult that encoded value to decide which action to take, which will require another if/else or switch upon the encoded value. It's all clumsy, verbose, slow and error prone.
Member function pointers
A better way is to use a more specialised varibale - a member function pointer - that directly records which action to perform at 6pm. That's what a member function pointer is. It's a kiss-or-tickle selector that's set earlier, creating a "state" for the monkey - is it a tickler or a kisser - which can be used later. The later code just invokes whatever function's been set without having to think about the possibilities or have any if/else-if or switch statements.
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
Back to this. So, this is good if you make the decision about which action to take at compile time (i.e. a point X in your program, it'll definitely be a tickle). Function pointers are for when you're not sure, and want to decouple the setting of actions from the invocation of those actions.

Accomplish this task in C++; Migration from AS3.0

I've got way too much information to work with, so for now I'll consider this question answered until I can sort it all out and decide on the final implementation! Thanks a ton gf and Simon Buchan. I wish I could accept both of your answers, since they're both definite possibilities!
Additional / Revised Conceptual Information as suggested:
What I am aiming to do;
I am making a game. In this game every object used is an instance of the DOBJ class. The TUR class extends the DOBJ class. The SHO class extends the TUR class.
Each TUR class has an array of SHO's stored in it's SHOARR array. Each SHO instance needs to be given a set of instructions.
I know for a fact I could make 1000's of different SHO classes that have their instructions set during construction.
However, considering I will have so many different acting SHO instances, I was interested in another way to pass a set of instructions. Through the contruction of the SHO would be the ideal.
The instructions I am attempting to pass to each SHO are simple if statements;
if(frame > 64) { rotation += 4; };
if(state == 0 && frame < 32) { xs = 12; ys = 12; state = 1; };
Original question
Migration from ActionScript3.0 to C++ is proving to be a trial indeed. Thanks to those who have answered my questions thus far and also to those who opened stackoverflow in the first place. Onto the question... (TL;DR near the bottom to get straight to the question)
I'm attempting to apply the same logic that I could apply in AS3.0 to my project in C++ and it's just not going very well.
In AS3.0 I was used to slapping any and every datatype into an Array. It made things pretty simple. Now that I've run into C++ dev, I realized that I can't exactly do that anymore.
So now I'm stuck with this problem of rewriting a little AI system in a new language, where the driving point of the system isn't even compatible!
Here's an example of a piece of the code I was writing in AS3.0;
AI[NUM][1]( OBJ, AI[NUM][2], AI[NUM][3] );
AI being an array, NUM being an integer, OBJ being an instance of a class.
This line obviously called the function in the second element of the first array in the main array with the arguments being a class in which to perform the function on, whatever was in the third element of the first array of the main array, and likewise the fourth element.
In this case;
AI[NUM][1] would be a function
AI[NUM][2] would be a variable
AI[NUM][3] would be a number
Generally, my AI was run on calling a function to change or compare the variable with a number.
An example would be;
CompareST( someObject, "x", 500 );
and return true if someObject's x variable was smaller than (ST) 500.
The AI array itself was just filled with arrays of calls similar to this.
Quite new to C++ I had no idea how to go about this, so I did a bit of searching and reading of many different websites and came to the conclusion that I should look into function pointers.
However, after reading a bit into them, I've come to the conclusion that it won't help me realize my goal. While it did help me call functions like I wanted to call them, it doesn't help me stack different datatypes into one large array of arrays.
TL;DR
EDIT++:
What I need for each object is a set of instructions to be checked every frame. However, for each instance of the class, the instructions have to be different.
I plan on having a LOT of different instances, so making a class for each one is unreasonable.
Thus, I needed a way to pass a set of instructions to each one through it's constructor and read + execute them at any time their think() function is called.
My ultimate goal (aside from finding out about a better way to go about this) would be to be able to have an array of function calls, like;
A[n][0]( O, A[n][1], A[n][2] );
Where;
O is the instance the function is altering
A[n][0] is a function (Equality or Comparison)
A[n][1] is the variable, eg; "x", O["x"] (or a pointer to that variable in the case of C++)
A[n][2] is the value to alter the variable by, or compare it to.
And I'm not sure how I would rewrite this into C++, or alter it to work in another way.
Aftermath / Additional Information
What I'm actually aiming to do is be able to give an object a set of instructions at the time of it's creation, through the constructor. For example upon creation give an object instructions to wait 64 frames, and then rotate in the opposite direction, would have been something like this;
t.AI = [ [ 1, AIF.CompareET, "STATE", 0, AIF.CompareGT, "FRAME", 64, 0, AIF.EqualityAT, "baseRotation", 180, AIF.EqualityET, "STATE", 1 ] ];
In pseudocode;
(The 1 in the array denotes how to read the rest of the array, in this case everything before the odd 0 [ The one that comes after 64 ] is a comparison. If any of those fail, anything after the 0 will not be looked at )
Compare STATE is equal to (ET) 0, if true
Compare FRAME is greather than (GT) 64, if true
Add 180 to (AT) baseRotation, Set STATE equal to 1
Sorry that this turned out really long. I hope it's understandable, and I'm not asking something stupidly difficult to explain.
You can store functions using function pointers or functors. Variant types though are not natively supported by C++, you have to use custom solutions there.
One possibility would be to use Boost.Any (or better, Boost.Variant if you only use a fixed set of types):
typedef void (*Function)(Object*, const std::string&, boost::any&);
std::vector<Function> functions;
Given some function:
void f(Object* obj, const std::string& name, boost::any& value) {
// ...
}
you could store and call it similar to your example:
functions.push_back(&f);
functions[0](obj, "x", boost::any(500));
To utilize a declarative syntax, there are three options that come to my mind:
you use a similar approach and have central "interpreter" function, e.g. based on a switch (don't forget to switch to integers or pointers-to-members instead of strings if you need performance)
you invent your own language and generate C++ code from description files
you compose function objects in a declarative way
To do composition, you could use Boost.Bind or something like custom objects that represent operations:
struct Operation {
virtual ~Operation() {}
virtual bool operator()(Object&) = 0;
};
template<class T>
struct GreaterThen : Operation {
typedef T Object::*Member;
Member member;
const T value;
CompareGT(Member member, const T& value) : member(member), value(value) {}
bool operator()(Object& obj) { return (obj.*member > value); }
};
template<class T>
struct SetTo : Operation {
typedef T Object::*member;
Member member;
const T value;
SetTo(Member member, const T& value) : member(member), value(value) {}
bool operator()(Object& obj) { obj.*member = value; return true; }
};
Now we can build operation lists:
typedef std::vector<Operation*> OpList;
OpList operation;
operations.push_back(new GreaterThen<int>(&Object::Frame, 64));
operations.push_back(new SetTo<int>(&Object::State, 1));
We can use helper functions to avoid having to specify the template types:
template<class T>
Operation* opGreaterThen(T Object::*mem, const T& val) {
return new GreaterThen<T>(mem, val);
}
Assuming a similar helper for SetTo and using Boost.Assign the above becomes:
OpList operations = boost::assign::list_of
(opGreaterThen(&Object::Frame, 64))
(opSetTo (&Object::State, 1));
Executing the operations becomes the following then:
OpList::iterator it = operation.begin();
for( ; it != operations.end(); ++it) {
Operation& op = *it; // just for readability
if(!op(someObject)) break; // stop if operation returns false
}
Wow.
Reading through that slowly suggests what you're trying to end up with is an array of function calls and you can choose a different function with the same parameters (but different implementation) for different actions and choose the correct one for the correct case.
If that is the case, you're looking for function pointers. Try this tutorial.
You should be able to use a function pointer with an argument set and point it to the correct function based on your needs. You won't need an array of function pointers for this either - any function that matches the definition should do. From the tutorial, declare a function pointer like this:
int (TMyClass::*functptr)(classname, int, int) = NULL; // C++
Then assign it later:
this.functptr = &TMyClass::doitthisway;
While it is possible (although a pain) to have an array of arbitrary types, you pretty much never need it, since you have to know something about what is where to do anything interesting with it: for example, your 'TL;DR' example seems to look something like:
struct AIRule {
// Can only handle comparing ints, see later for more general solution.
typedef bool compare_type(AIObject*, AIObject::*int, int);
compare_type* compare;
AIObject* object;
AIObject::int* member;
int comparand;
};
So now you can do something like:
bool ai_equal(AIObject* object, AIObject::int* member, int comparand) {
return object->*member == comparand;
}
...
ai[n].compare = &ai_equal;
ai[n].object = some_object;
ai[n].member = &AIObject::some_member;
ai[n].comparand = 50;
...
if (ai[n].compare(ai[n].object, ai[n].member, ai[n].comparand)) {
...
}
This just moves the any type problem from the rules array to member though. C++ needs to know at least how many bytes a member is, and a string (for example) can be much bigger than an int. You can get around this by using pointers: which essentially is C++'s version of any, but you then need to delete it yourself (or you will leak memory!), at which point the interface method below becomes simpler.
If I was doing what you seem to want, I would use inheritance:
struct Sprite {
int frame;
double rotation;
Sprite() {
frame = 0;
rotation = 0.0;
}
virtual ~Sprite() {}
virtual void think() {
++frame;
}
virtual void draw() {
...
}
};
struct RotatingSprite : public Sprite {
int state;
MyShape() {
state = 0;
}
void think() {
Sprite::think();
if (state == 0 && frame > 64) {
state = 1;
rotation += 180.0;
}
}
};
Or a function pointer:
struct Sprite {
int frame;
double rotation;
void (*think)(Sprite*);
Sprite() {
frame = 0;
rotation = 0.0;
}
};
void rotate_think(Sprite* sprite) {
if (sprite->state == 0 && sprite->frame > 64) {
sprite->state = 1;
sprite->rotation += 180.0;
}
}
...
sprite->think = &rotate_think;
If you really need to do it dynamically I would recommend using the ++ part of C++. For the predicates (a predicate is just something that returns a boolean, like isLowerCase()) create an AIPredicate interface, and the actions an AIAction interface:
struct AIPredicate {
// "When you delete an AIPredicate, delete the full type, not just this interface."
virtual ~AIPredicate() {}
// "You can treat this as a function (operator()) but I'm not providing an implementation here ( = 0)"
virtual bool operator()(AIObject* object) = 0;
};
struct AIAction {
virtual ~AIAction() {}
virtual void operator()(AIObject* object) = 0;
};
struct AIRule {
// std::auto_ptr (or std::unique_ptr if you can use C++0x) will delete predicate for you.
// Add "#include <memory>" to your includes if it complains (most std headers will include it already)
std::auto_ptr<AIPredicate> predicate;
std::auto_ptr<AIAction> action;
};
Now you can make types like:
struct AIFrame : public AIPredicate {
// Implement the operator() member AICondition promises.
bool operator()(AIObject* object) {
return object->foo < 100;
}
};
...
// Use .reset() instead of = if you use std::unique_ptr.
ai[n].predicate = new AIFooIsLow();
If you want to have a very general predicate type, you can use the very powerful (and complicated) templates feature:
// The naming convention I'm using here is 'T'TitleCase for template parameters, TitleCase for types,
// lower_case for arguments and variables and '_'lower_case for members.
template<typename TMemberType, AIObject::TMemberType* TMember>
struct AIMemberEquals : public AIPredicate {
// Constructor: Initializes a new instance after it is created.
AIMemberEquals(TMemberType comparand) {
// Save comparand argument so we can use it in operator().
_comparand = comparand;
}
bool operator()(AIObject* object) {
return object->*TMember == comparand;
}
// Stores the value to compare.
TMemberType _comparand;
};
Unfortunately, creating templates looks a bit crazy:
ai[n].predicate = new AIMemberEquals<int, &AIObject::some_member>(100);
Read it as "create a new instance of (the type that AIMemberEquals applied to int and (the some_member member of AIObject) creates), with the argument 100".
When you have multiple predicates memory management becomes a bit more difficult without C++0x's unique_ptr or shared_ptr, types that will delete the object for you, since std::auto_ptr doesn't work in containers:
#include <vector>
struct AIData {
// vector is fairly close to AS3's Array type, it is a good default for
// arrays of changing or unknown size.
std::vector<AIPredicate*> predicates;
// Destructor: will be run before the memory for this object is freed.
~AIData() {
for (int i = 0; i != predicates.size(); ++i) {
delete predicates[i];
}
}
};
...
ai[n].predicates.push_back(new AIFooIsLow());
...
for (int i = 0; i != ai[n].predicates.size(); ++i) {
(*ai[n].predicates[i])(ai[n].object);
}
In C++0x:
struct AIData {
// unique_ptr will delete it for you, so no ~AIData() needed.
std::vector<unique_ptr<AIPredicate>> predicates;
};
Your final example could in C++ look something like:
std::auto_ptr<Shape> shape(new Shape());
...
std::auto_ptr<AIRule> rule(new AIRule());
rule->predicates.push(new AIMemberEquals<int, &Shape::state>(0));
rule->predicates.push(new AIMemberGreater<int, &Shape::frame>(64));
rule->actions.push(new AIAddMember<double, &Shape::rotation>(180.0));
rule->actions.push(new AISetMember<int, &Shape::state>(1));
shape->ai.push(rule); // .push(std::move(rule)); if you are using unique_ptr
Certainly not as pretty, but it works and is fairly flexible.

Storing a list of arbitrary objects in C++

In Java, you can have a List of Objects. You can add objects of multiple types, then retrieve them, check their type, and perform the appropriate action for that type.
For example: (apologies if the code isn't exactly correct, I'm going from memory)
List<Object> list = new LinkedList<Object>();
list.add("Hello World!");
list.add(7);
list.add(true);
for (object o : list)
{
if (o instanceof int)
; // Do stuff if it's an int
else if (o instanceof String)
; // Do stuff if it's a string
else if (o instanceof boolean)
; // Do stuff if it's a boolean
}
What's the best way to replicate this behavior in C++?
boost::variant is similar to dirkgently's suggestion of boost::any, but supports the Visitor pattern, meaning it's easier to add type-specific code later. Also, it allocates values on the stack rather than using dynamic allocation, leading to slightly more efficient code.
EDIT: As litb points out in the comments, using variant instead of any means you can only hold values from one of a prespecified list of types. This is often a strength, though it might be a weakness in the asker's case.
Here is an example (not using the Visitor pattern though):
#include <vector>
#include <string>
#include <boost/variant.hpp>
using namespace std;
using namespace boost;
...
vector<variant<int, string, bool> > v;
for (int i = 0; i < v.size(); ++i) {
if (int* pi = get<int>(v[i])) {
// Do stuff with *pi
} else if (string* si = get<string>(v[i])) {
// Do stuff with *si
} else if (bool* bi = get<bool>(v[i])) {
// Do stuff with *bi
}
}
(And yes, you should technically use vector<T>::size_type instead of int for i's type, and you should technically use vector<T>::iterator instead anyway, but I'm trying to keep it simple.)
Your example using Boost.Variant and a visitor:
#include <string>
#include <list>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
using namespace std;
using namespace boost;
typedef variant<string, int, bool> object;
struct vis : public static_visitor<>
{
void operator() (string s) const { /* do string stuff */ }
void operator() (int i) const { /* do int stuff */ }
void operator() (bool b) const { /* do bool stuff */ }
};
int main()
{
list<object> List;
List.push_back("Hello World!");
List.push_back(7);
List.push_back(true);
BOOST_FOREACH (object& o, List) {
apply_visitor(vis(), o);
}
return 0;
}
One good thing about using this technique is that if, later on, you add another type to the variant and you forget to modify a visitor to include that type, it will not compile. You have to support every possible case. Whereas, if you use a switch or cascading if statements, it's easy to forget to make the change everywhere and introduce a bug.
C++ does not support heterogenous containers.
If you are not going to use boost the hack is to create a dummy class and have all the different classes derive from this dummy class. Create a container of your choice to hold dummy class objects and you are ready to go.
class Dummy {
virtual void whoami() = 0;
};
class Lizard : public Dummy {
virtual void whoami() { std::cout << "I'm a lizard!\n"; }
};
class Transporter : public Dummy {
virtual void whoami() { std::cout << "I'm Jason Statham!\n"; }
};
int main() {
std::list<Dummy*> hateList;
hateList.insert(new Transporter());
hateList.insert(new Lizard());
std::for_each(hateList.begin(), hateList.end(),
std::mem_fun(&Dummy::whoami));
// yes, I'm leaking memory, but that's besides the point
}
If you are going to use boost you can try boost::any. Here is an example of using boost::any.
You may find this excellent article by two leading C++ experts of interest.
Now, boost::variant is another thing to look out for as j_random_hacker mentioned. So, here's a comparison to get a fair idea of what to use.
With a boost::variant the code above would look something like this:
class Lizard {
void whoami() { std::cout << "I'm a lizard!\n"; }
};
class Transporter {
void whoami() { std::cout << "I'm Jason Statham!\n"; }
};
int main() {
std::vector< boost::variant<Lizard, Transporter> > hateList;
hateList.push_back(Lizard());
hateList.push_back(Transporter());
std::for_each(hateList.begin(), hateList.end(), std::mem_fun(&Dummy::whoami));
}
How often is that sort of thing actually useful? I've been programming in C++ for quite a few years, on different projects, and have never actually wanted a heterogenous container. It may be common in Java for some reason (I have much less Java experience), but for any given use of it in a Java project there might be a way to do something different that will work better in C++.
C++ has a heavier emphasis on type safety than Java, and this is very type-unsafe.
That said, if the objects have nothing in common, why are you storing them together?
If they do have things in common, you can make a class for them to inherit from; alternately, use boost::any. If they inherit, have virtual functions to call, or use dynamic_cast<> if you really have to.
I'd just like to point out that using dynamic type casting in order to branch based on type often hints at flaws in the architecture. Most times you can achieve the same effect using virtual functions:
class MyData
{
public:
// base classes of polymorphic types should have a virtual destructor
virtual ~MyData() {}
// hand off to protected implementation in derived classes
void DoSomething() { this->OnDoSomething(); }
protected:
// abstract, force implementation in derived classes
virtual void OnDoSomething() = 0;
};
class MyIntData : public MyData
{
protected:
// do something to int data
virtual void OnDoSomething() { ... }
private:
int data;
};
class MyComplexData : public MyData
{
protected:
// do something to Complex data
virtual void OnDoSomething() { ... }
private:
Complex data;
};
void main()
{
// alloc data objects
MyData* myData[ 2 ] =
{
new MyIntData()
, new MyComplexData()
};
// process data objects
for ( int i = 0; i < 2; ++i ) // for each data object
{
myData[ i ]->DoSomething(); // no type cast needed
}
// delete data objects
delete myData[0];
delete myData[1];
};
Sadly there is no easy way of doing this in C++. You have to create a base class yourself and derive all other classes from this class. Create a vector of base class pointers and then use dynamic_cast (which comes with its own runtime overhead) to find the actual type.
Just for completeness of this topic I want to mention that you can actually do this with pure C by using void* and then casting it into whatever it has to be (ok, my example isn't pure C since it uses vectors but that saves me some code). This will work if you know what type your objects are, or if you store a field somewhere which remembers that. You most certainly DON'T want to do this but here is an example to show that it's possible:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a = 4;
string str = "hello";
vector<void*> list;
list.push_back( (void*) &a );
list.push_back( (void*) &str );
cout << * (int*) list[0] << "\t" << * (string*) list[1] << endl;
return 0;
}
While you cannot store primitive types in containers, you can create primitive type wrapper classes which will be similar to Java's autoboxed primitive types (in your example the primitive typed literals are actually being autoboxed); instances of which appear in C++ code (and can (almost) be used) just like primitive variables/data members.
See Object Wrappers for the Built-In Types from Data Structures and Algorithms with Object-Oriented Design Patterns in C++.
With the wrapped object you can use the c++ typeid() operator to compare the type.
I am pretty sure the following comparison will work:
if (typeid(o) == typeid(Int)) [where Int would be the wrapped class for the int primitive type, etc...]
(otherwise simply add a function to your primitive wrappers that returns a typeid and thus:
if (o.get_typeid() == typeid(Int)) ...
That being said, with respect to your example, this has code smell to me.
Unless this is the only place where you are checking the type of the object,
I would be inclined to use polymorphism (especially if you have other methods/functions specific with respect to type). In this case I would use the primitive wrappers adding an interfaced class declaring the deferred method (for doing 'do stuff') that would be implemented by each of your wrapped primitive classes. With this you would be able to use your container iterator and eliminate your if statement (again, if you only have this one comparison of type, setting up the deferred method using polymorphism just for this would be overkill).
I am a fairly inexperienced, but here's what I'd go with-
Create a base class for all classes you need to manipulate.
Write container class/ reuse container class.
(Revised after seeing other answers -My previous point was too cryptic.)
Write similar code.
I am sure a much better solution is possible. I am also sure a better explanation is possible. I've learnt that I have some bad C++ programming habits, so I've tried to convey my idea without getting into code.
I hope this helps.
Beside the fact, as most have pointed out, you can't do that, or more importantly, more than likely, you really don't want to.
Let's dismiss your example, and consider something closer to a real-life example. Specifically, some code I saw in a real open-source project. It attempted to emulate a cpu in a character array. Hence it would put into the array a one byte "op code", followed by 0, 1 or 2 bytes which could be a character, an integer, or a pointer to a string, based on the op code. To handle that, it involved a lot of bit-fiddling.
My simple solution: 4 separate stacks<>s: One for the "opcode" enum and one each for chars, ints and string. Take the next off the opcode stack, and the would take you which of the other three to get the operand.
There's a very good chance your actual problem can be handled in a similar way.
Well, you could create a base class and then create classes which inherit from it. Then, store them in a std::vector.
The short answer is... you can't.
The long answer is... you'd have to define your own new heirarchy of objects that all inherit from a base object. In Java all objects ultimately descend from "Object", which is what allows you to do this.
RTTI (Run time type info) in C++ has always been tough, especially cross-compiler.
You're best option is to use STL and define an interface in order to determine the object type:
public class IThing
{
virtual bool isA(const char* typeName);
}
void myFunc()
{
std::vector<IThing> things;
// ...
things.add(new FrogThing());
things.add(new LizardThing());
// ...
for (int i = 0; i < things.length(); i++)
{
IThing* pThing = things[i];
if (pThing->isA("lizard"))
{
// do this
}
// etc
}
}
Mike