struct Pt {
double x, y;
};
struct Mesh {
std::vector<Pt> pts;
int AddPtI(Pt pt) { pts.push_back(pt); return pts.size(); };
int AddPtI(double x, double y) { Pt pt; pt.x = x, pt.y = y; pts.push_back(pt); return pts.size(); };
int AddPtI(std::vector<double> pts_in) { Pt pt; pt.x = pts_in[0], pt.y = pts_in[1]; pts.push_back(pt); return pts.size(); };
void AddPtV(Pt pt) { pts.push_back(pt); };
void AddPtV(double x, double y) { Pt pt; pt.x = x, pt.y = y; pts.push_back(pt); };
void AddPtV(std::vector<double> pts_in) { Pt pt; pt.x = pts_in[0], pt.y = pts_in[1]; pts.push_back(pt); };
};
std::vector<Pt> pts;
int AddPtI(Pt pt) { pts.push_back(pt); return pts.size(); };
int AddPtI(double x, double y) { Pt pt; pt.x = x, pt.y = y; pts.push_back(pt); return pts.size(); };
int AddPtI(std::vector<double> pts_in) { Pt pt; pt.x = pts_in[0], pt.y = pts_in[1]; pts.push_back(pt); return pts.size(); };
void AddPtV(Pt pt) { pts.push_back(pt); };
void AddPtV(double x, double y) { Pt pt; pt.x = x, pt.y = y; pts.push_back(pt); };
void AddPtV(std::vector<double> pts_in) { Pt pt; pt.x = pts_in[0], pt.y = pts_in[1]; pts.push_back(pt); };
The following is a stab at the syntax the user would use to bind functions and load from a file.
ObjReader::BindFunc<Mesh, void, Pt>(&Mesh::AddPtV);
ObjReader::BindFunc< Mesh, void, std::vector<double> > (&Mesh::AddPtV);
ObjReader::Load(meshInstance, " file.obj ");
ObjReader::Load("file.obj");I'm making (slow) progress using the following three articles as my principle reference: * style Case Study #2: Generic Callbacks (Herb Sutter) [http://www.gotw.ca/gotw/083.htm] covers the basics. * Delegate in Standard C++ (Ben Chun Pong Chan) [http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4119] adds non-member function support. * C++ Callback Solution (Arash Partow) [http://www.partow.net/programming/templatecallback/index.html] adds multiple argument support. (Template parameters are fully named which makes it easier to understand what's what.) It looks as though this is the Command pattern. So far, my implementation looks something like this:class ObjReader {
public:
static CallbackBase* cb;
template<typename T, typename R, typename A>
static void BindFunc(R (T::*f)(A)) {
static Callback3<T,R,A> cb1(f);
cb = &cb1
// 2/ at this point we know the function type etc
// so now would be ideal time to set up the associated line parse function... but how
};
static void Load(void* meshInstance , std::string filename) {
std::vector<double> pt;
pt.push_back(10);
pt.push_back(11);
cb(meshInstance, pt); // 1/ doesn't work 'cos doesn't know underlying type of cb
}
}So far, I've encountered the following problems: 1/ The ObjReader keeps track of the function pointers with a pointer to a base class static CallbackBase* cb, so when it comes time to invoke the function there is no way to identify its type. There seem to be two ways around this; casting to the appropriate type when needed (but to which type), or do away with the container and have n pointers, one for each supported function. 2/ When the ObjReader parses a line how can it identify the native or user defined type and process it accordingly? The following is not legal:// for std::vector<number> - a container of any type
template<typename T>
static void ParsePoint () {
T f1, f2;
m_fileStream >> f1 >> f2;
vector<T> pt;
pt.push_back(f1);
pt.push_back(f2);
AddPoint(pt);
};
// for 2-tuple – any type that has x and y
template<typename T>
static void ParsePoint () {
T t;
m_fileStream >> t.x >> t.y;
AddPoint(pt);
};The functions could have different names, but still, how would I select the correct function and set up a pointer? Is it possible (or necessary to store the argument type(s) when the function is bound? This looks like it may be the Bridge, Adapter, Letter/Envelope or Handle/Body Pattern. I'm hoping there is some way to tackle the issues I've encountered, so any pointers would be most welcome (no pun intended). I'm trying to do this in "vanilla" C++, so BOOST, LOKI, etc. aren't options. TIA A5