template for multiple functions with varying arg list

I know C very well, and C++ fairly well. Although - with the latter - I never really had a need to use templates.

Now I am doing a project that seems like a good candidate for them. Simply put: I am wrapping a 3rd party C library into C++ classes. There are many C functions of the form:

[return type] funA(arg1,...,argN, void* data){};

From that, I would like to generate:
return (ClassX *)data)->m_funA(arg1, ..., argN);

where data is actually the this pointer to the object making the function call. I know that the above format works, but I would just like to put the general form into a template. The member function would contain the actual code.

Any suggestions?

TIA






Last edited on
From that, I would like to generate:
return (ClassX *)data)->m_funA(arg1, ..., argN);
It would be helpful to demonstrate the semantics you want in context. (I mean, use the interface of the template function in some contrived example).
After that, hopefully I will be able to help.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ClassX public
{
	ClassX(){
	    m_c_handle = c_funGetHandle();
	   
	   /* set callback function: args are: handle, address of static callback function, void pointer to user data */
		c_SetCB(m_c_handle, &ClassX::cbfun1, (void*)this);};
	virtual ~ClassX();
	
	/* C++ to C: funA ... funX */

               [return type]	cpp_funA(arg1, ..., argN){return c_funA(m_c_handle, arg1, ..., argN);};
               
                   /*  cpp call back function  */
	virtual    [return type]	cpp_cbfun1(arg1, ..., argN);

protected:	
		[handle_type]	m_c_handle;

private:
	/* c callback function 1 (needs to be static to get the address when setting the callback) */
	static [return type] 	c_cbfun1( arg1, ..., argN, void* data){return ((ClassX*)data)->cpp_cbfun1(arg1, ..., argN);};
};


This is the base class. There are two types of functions: those that just wrap a C call (inserting the first arg as a handle for this particular instance; the other is a callback function, where the user data is a pointer to the object. The latter casts the void data pointer to the class object, and then calls the corresponding C++ member function. The member function is virtual, to allow the developer to use his own code for the callback.

I would like to use templates to generate multiple cpp_funX and c_cbfunN/cpp_cbfunN functions.

I hope this is a bit clearer. As I said, I don't know much about templates, so I really don't know what they can or can't do. If they can simplify writing out all of the funN's and cbfunN's, that would be a bit helpful.

Thanks,

ken
If they can simplify writing out all of the funN's and cbfunN's, that would be a bit helpful.
You just described a macro, but, the purpose of templates is to help enable type-safe generic code.

Templates accomplish this roughly by generating classes and function overloads on request, but the mechanism isn't general enough to stick arbitrary code anywhere you want. Templates allow you to generate classes and functions based on their (static) type, and make decisions (only) at compile-time based on the overload resolution rules.

Just some notes:
You should know about the generalized call wrapper std::function<>:
http://en.cppreference.com/w/cpp/utility/functional/function

Functions are not the only things that can be called. Objects with an overloaded operator() can be called too, even stateful ones. Because this allows the creation of closures, this allows C++ to (nicely) make use of the entire gamut of higher-order (functional) programming techniques. C has no such core language support, so I can't begin to guess whether you actually need what you're asking for, or if you're chasing the wrong solution.
http://en.cppreference.com/w/cpp/language/lambda

The solution as it stands ("help me write these functions") is probably a preprocessor macro. I doubt this is actually what you want, though: this seems like an XY problem:
xyproblem.info
What's your actual goal?

I hope someone else can provide more insight than me! :)
Last edited on
@mbozzi: No, you basically answered my question - at least in a general sense. As I said, I really don't much about c++ templates,. I did know that they were used to handle data types across different platforms. But that is not what I am doing here - in fact, the platform (os,architecture, et al.) is fixed.

The goal, as I mentioned at first, is to take a third party C library, wrap those (C) calls within a C++ class, and then possibly build higher level classes that would hide most of the original C functions. That would allow the developer to know very little about the actual C library calls, and concentrate of the app.

For the C library, there are many functions with similar signatures: they all would take a handle, and would pass a pointer to user data; but they also had varying number and types of additional args, including the return type. I was hoping that templates might have a better way to handle that, rather than with macros (macros are cumbersome, prone to bugs, ugly, and just plain suck).

And, basically, I didn't know what the capabilities of templates were. I did see once a template used to define a function format - the return type and types of args. But maybe that was also to handle different platforms as well.

Thanks for the clarification for me. I guess I'll just have to do a lot of typing :-(.
With bind you can attach arbitrary parameter to a function object:

http://www.cplusplus.com/reference/functional/bind/?kw=bind

Event the this parameter for a member function works. It is always the first parameter.
By "generic code" I mean "code which accepts any type which meets a particular interface". Templates are certainly not limited to a tool for aiding platform-independence; templates and template meta-programming are absolutely crucial to modern C++.

You can in fact write a template function which accepts any number of arguments with types known at compile time, but you still have to forward those arguments to a set of totally unrelated symbols. This can't be done entirely automatically, since you have to specify the symbol names.

However, I pointed out closures to you for a reason.... @coder777 hinted at this too.
It's simple to fix the first argument to an arbitrary function (i.e., to a handle) and call it with the right number of arguments. Borrow from functional programming a little bit.

In addition to @coder777's link, see JLBorges' and my posts in this thread:
http://www.cplusplus.com/forum/general/211067/

Just a note: re. std::bind. it's a tool for partial function application, but it's arcane looking, quite unidiomatic, and limited by the number of available placeholders. For this reason, I suggest that you prefer closures (simpler, more readable, more idiomatic) instead.
Last edited on
Topic archived. No new replies allowed.