I have a function written in Java which accepts varargs as an argument. I wanted to port that function to C++. I tried to search but the closest I got is using std::vector of argument list. What would be the best way to convert varargs to C++? the function is as below.
public EventHandlerQueue<T> get (final EventHandler<T> ... handlers)
{
// Do something with handlers
return new EventHandlerQueue<T>(handlers)
}
I wanted to port that function to C++. I tried to search but the
closest I got is using std::vector of argument list.
Which is exactly correct, and exactly what the Java varags list actually is, just with some different syntax.
varargs in Java is pure syntactic sugar. It get's translated by the compiler into a call to the function passing/receiving an array of EventHandler<T>.
The closest in C++11 would be std::initializer_list<EventHandler<T>> where you will need to encapsulate the arguments in an extra pair of curly braces:
EventHandlerQueue<T> get(std::initailizer_list<EventHandler<T>> handlers);
obj.get( {EventHandler1, EventHandler2} );
// asuming that `obj` is an object for which the above member is defined.
In C++03 there is no similar syntactic sugar and you will need to create an array/vector and pass it. Since arrays have statically defined sizes, the best option here is just passing a std::vector<EventHandler<T> >.
In C++ these are 'variadic templates', as #chris says.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=138
http://en.wikipedia.org/wiki/Variadic_templates
Wikipedia's example:
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%' && *(++s) != '%') {
std::cout << value;
++s;
printf(s, args...); // call even when *s == 0 to detect extra arguments
return;
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
Related
The Goal:
decide during runtime which templated function to use and then use it later without needing the type information.
A Partial Solution:
for functions where the parameter itself is not templated we can do:
int (*func_ptr)(void*) = &my_templated_func<type_a,type_b>;
this line of code can be modified for use in an if statement with different types for type_a and type_b thus giving us a templated function whose types are determined during runtime:
int (*func_ptr)(void*) = NULL;
if (/* case 1*/)
func_ptr = &my_templated_func<int, float>;
else
func_ptr = &my_templated_func<float, float>;
The Remaining Problem:
How do I do this when the parameter is a templated pointer?
for example, this is something along the lines of what I would like to do:
int (*func_ptr)(templated_struct<type_a,type_b>*); // This won't work cause I don't know type_a or type_b yet
if (/* case 1 */) {
func_ptr = &my_templated_func<int,float>;
arg = calloc(sizeof(templated_struct<int,float>, 1);
}
else {
func_ptr = &my_templated_func<float,float>;
arg = calloc(sizeof(templated_struct<float,float>, 1);
}
func_ptr(arg);
except I would like type_a, and type_b to be determined during runtime. I see to parts to the problem.
What is the function pointers type?
How do I call this function?
I think I have the answer for (2): simply cast the parameter to void* and the template function should do an implicit cast using the function definition (lease correct me if this won't work as I think it will).
(1) is where I am getting stuck since the function pointer must include the parameter types. This is different from the partial solution because for the function pointer definition we were able to "ignore" the template aspect of the function since all we really need is the address of the function.
Alternatively there might be a much better way to accomplish my goal and if so I am all ears.
Thanks to the answer by #Jeffrey I was able to come up with this short example of what I am trying to accomplish:
template <typename A, typename B>
struct args_st {
A argA;
B argB;
}
template<typename A, typename B>
void f(struct args_st<A,B> *args) {}
template<typename A, typename B>
void g(struct args_st<A,B> *args) {}
int someFunction() {
void *args;
// someType needs to know that an args_st struct is going to be passed
// in but doesn't need to know the type of A or B those are compiled
// into the function and with this code, A and B are guaranteed to match
// between the function and argument.
someType func_ptr;
if (/* some runtime condition */) {
args = calloc(sizeof(struct args_st<int,float>), 1);
f((struct args_st<int,float> *) args); // this works
func_ptr = &g<int,float>; // func_ptr should know that it takes an argument of struct args_st<int,float>
}
else {
args = calloc(sizeof(struct args_st<float,float>), 1);
f((struct args_st<float,float> *) args); // this also works
func_ptr = &g<float,float>; // func_ptr should know that it takes an argument of struct args_st<float,float>
}
/* other code that does stuff with args */
// note that I could do another if statement here to decide which
// version of g to use (like I did for f) I am just trying to figure out
// a way to avoid that because the if statement could have a lot of
// different cases similarly I would like to be able to just write one
// line of code that calls f because that could eliminate many lines of
// (sort of) duplicate code
func_ptr(args);
return 0; // Arbitrary value
}
Can't you use a std::function, and use lambdas to capture everything you need? It doesn't appear that your functions take parameters, so this would work.
ie
std::function<void()> callIt;
if(/*case 1*/)
{
callIt = [](){ myTemplatedFunction<int, int>(); }
}
else
{
callIt = []() {myTemplatedFunction<float, float>(); }
}
callIt();
If I understand correctly, What you want to do boils down to:
template<typename T>
void f(T)
{
}
int somewhere()
{
someType func_ptr;
int arg = 0;
if (/* something known at runtime */)
{
func_ptr = &f<float>;
}
else
{
func_ptr = &f<int>;
}
func_ptr(arg);
}
You cannot do that in C++. C++ is statically typed, the template types are all resolved at compile time. If a construct allowed you to do this, the compiler could not know which templates must be instanciated with which types.
The alternatives are:
inheritance for runtime polymorphism
C-style void* everywhere if you want to deal yourself with the underlying types
Edit:
Reading the edited question:
func_ptr should know that it takes an argument of struct args_st<float,float>
func_ptr should know that it takes an argument of struct args_st<int,float>
Those are incompatible. The way this is done in C++ is by typing func_ptr accordingly to the types it takes. It cannot be both/all/any.
If there existed a type for func_ptr so that it could take arguments of arbitrary types, then you could pass it around between functions and compilation units and your language would suddenly not be statically typed. You'd end up with Python ;-p
Maybe you want something like this:
#include <iostream>
template <typename T>
void foo(const T& t) {
std::cout << "foo";
}
template <typename T>
void bar(const T& t) {
std::cout << "bar";
}
template <typename T>
using f_ptr = void (*)(const T&);
int main() {
f_ptr<int> a = &bar<int>;
f_ptr<double> b = &foo<double>;
a(1);
b(4.2);
}
Functions taking different parameters are of different type, hence you cannot have a f_ptr<int> point to bar<double>. Otherwise, functions you get from instantiating a function template can be stored in function pointers just like other functions, eg you can have a f_ptr<int> holding either &foo<int> or &bar<int>.
Disclaimer: I have already provided an answer that directly addresses the question. In this answer, I would like to side-step the question and render it moot.
As a rule of thumb, the following code structure is an inferior design in most procedural languages (not just C++).
if ( conditionA ) {
// Do task 1A
}
else {
// Do task 1B
}
// Do common tasks
if ( conditionA ) {
// Do task 2A
}
else {
// Do task 2B
}
You seem to have recognized the drawbacks in this design, as you are trying to eliminate the need for a second if-else in someFunction(). However, your solution is not as clean as it could be.
It is usually better (for code readability and maintainability) to move the common tasks to a separate function, rather than trying to do everything in one function. This gives a code structure more like the following, where the common tasks have been moved to the function foo().
if ( conditionA ) {
// Do task 1A
foo( /* arguments might be needed */ );
// Do task 2A
}
else {
// Do task 1B
foo( /* arguments might be needed */ );
// Do task 2B
}
As a demonstration of the utility of this rule of thumb, let's apply it to someFunction(). ... and eliminate the need for dynamic memory allocation ... and a bit of cleanup ... unfortunately, addressing that nasty void* is out-of-scope ... I'll leave it up to the reader to evaluate the end result. The one feature I will point out is that there is no longer a reason to consider storing a "generic templated function pointer", rendering the asked question moot.
// Ideally, the parameter's type would not be `void*`.
// I leave that for a future refinement.
void foo(void * args) {
/* other code that does stuff with args */
}
int someFunction(bool condition) {
if (/* some runtime condition */) {
args_st<int,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
else {
args_st<float,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
return 0;
}
Your choice of manual memory management and over-use of the keyword struct suggests you come from a C background and have not yet really converted to C++ programming. As a result, there are many areas for improvement, and you might find that your current approach should be tossed. However, that is a future step. There is a learning process involved, and incremental improvements to your current code is one way to get there.
First, I'd like to get rid of the C-style memory management. Most of the time, using calloc in C++ code is wrong. Let's replace the raw pointer with a smart pointer. A shared_ptr looks like it will help the process along.
// Instead of a raw pointer to void, use a smart pointer to void.
std::shared_ptr<void> args;
// Use C++ memory management, not calloc.
args = std::make_shared<args_st<int,float>>();
// or
args = std::make_shared<args_st<float,float>>();
This is still not great, as it still uses a pointer to void, which is rarely needed in C++ code unless interfacing with a library written in C. It is, though, an improvement. One side effect of using a pointer to void is the need for casts to get back to the original type. This should be avoided. I can address this in your code by defining correctly-typed variables inside the if statement. The args variable will still be used to hold your pointer once the correctly-typed variables go out of scope.
More improvements along this vein can come later.
The key improvement I would make is to use the functional std::function instead of a function pointer. A std::function is a generalization of a function pointer, able to do more albeit with more overhead. The overhead is warranted here in the interest of robust code.
An advantage of std::function is that the parameter to g() does not need to be known by the code that invokes the std::function. The old style of doing this was std::bind, but lambdas provide a more readable approach. Not only do you not have to worry about the type of args when it comes time to call your function, you don't even need to worry about args.
int someFunction() {
// Use a smart pointer so you do not have to worry about releasing the memory.
std::shared_ptr<void> args;
// Use a functional as a more convenient alternative to a function pointer.
// Note the lack of parameters (nothing inside the parentheses).
std::function<void()> func;
if ( /* some runtime condition */ ) {
// Start with a pointer to something other than void.
auto real_args = std::make_shared<args_st<int,float>>();
// An immediate function call:
f(real_args.get());
// Choosing a function to be called later:
// Note that this captures a pointer to the data, not a copy of the data.
// Hence changes to the data will be reflected when this is invoked.
func = [real_args]() { g(real_args.get()); };
// It's only here, as real_args is about to go out of scope, where
// we lose the type information.
args = real_args;
}
else {
// Similar to the above, so I'll reduce the commentary.
auto real_args = std::make_shared<args_st<float,float>>();
func = [real_args]() { g(real_args.get()); };
args = real_args;
}
/* other code that does stuff with args */
/* This code is probably poor C++ style, but that can be addressed later. */
// Invoke the function.
func();
return 0;
}
Your next step probably should be to do some reading on these features so you understand what this code does. Then you should be in a better position to leverage the power of C++.
I have a legacy C code base, which I am migrating to C++ in a piecemeal fashion. It includes an interpreter, so there is a need to wrap static functions and arguments for use by the interpreter. So a typical function for export to the interpreter may have the following signature:
static void do_strstr(struct value * p)
and be exposed to the interpreter like so:
using vptr = void (*) ();
template <typename Func>
constexpr vptr to_vptr(Func && func)
{ return reinterpret_cast<vptr>(func); }
struct function string_funs[] = {
...
{ C_FN3, X_A3, "SSI", to_vptr(do_strstr), "find" },
...
};
This has been proven to work. The drawback with the method so far is that the called function must allocate memory onto a temporary stack. An improvement would be where the called function just returns a string, for example. This function is then wrapped, where the wrapper does the memory magic behind the scenes. This allows functions to created in a more vanilla way.
Here is an implementation which concatenates two strings using my improved method:
static std::string do_concata(struct value* p)
{
std::string s1 = (p)->gString();
std::string s2 = (p+1)->gString();
return s1+s2;
}
I create a helper function:
static void do_concata_1(struct value* p)
{
wrapfunc(do_concata)(p);
}
where the somewhat generic wrapper is defined as:
std::function<void(struct value*)>
wrapfunc(std::function<std::string(struct value*)> func)
{
auto fn = [=](struct value* p) {
std::string s = func(p);
char* ret = alloc_tmp_mem(s.size()+1);
strcpy(ret, s.c_str());
p->sString(ret);
return;
};
return fn;
}
which is exposed to the interpreter as follows:
struct function string_funs[] = {
...
{ C_FN2, X_A2, "SS", to_vptr(do_concata_1), "concata" },
...
};
I am not satisfied with this solution, though, as it requires a helper function for each function I define. It would be better if I could eliminate do_concata_1 and write another function that wraps the wrapfunc.
And this is where the problem is. If I write:
vptr to_vptr_1(std::function<void(struct value*)> func)
{
return to_vptr(wrapfunc(func));
}
then the compiler complains:
stringo.cc: In function ‘void (* to_vptr_1(std::function<void(value*)>))()’:
stringo.cc:373:30: error: could not convert ‘func’ from ‘std::function<void(value*)>’ to ‘std::function<std::__cxx11::basic_string<char>(value*)>’
return to_vptr(wrapfunc(func));
which is bizarre in my mind, because where did the std::__cxx11::basic_string<char> come from? It should be void, surely?
I'm at a loss to see what the fix should be. I am also a bit confused as to whether I should be passing copies of functions, references to functions, or the enigmatic && r-vale references.
In to_vptr_1(), func is established as a function that returns void. But func is passed to wrapfunc(), which expects a function that returns std::string. The compiler does not have a way to convert func from std::function<void(struct value*)> to std::function<std::string(struct value*)>, so it emits the error message.
reinterpret_cast from std::function to raw function pointer is not going to work. This question has some good discussion on the topic, and this one has a solution that could perhaps be reworked for this situation.
Hello Guys so i want to code something in C++ that i have for C# but as there is no params object in C++ i need some help :P
Ok, so here's what i want to do:
static Int32 Procedure(UInt32 address, params Object[] parameters)
{
Int32 length = parameters.Length;
Int32 index = 0;
UInt32 count = 0;
UInt32 Strings = 0;
UInt32 Single = 0;
UInt32 Array = 0;
while (index < length)
{
if (parameters[index] is Int32)
{
WriteInt32(0x10050000 + (count * 4), (Int32)parameters[index]);
count++;
}
else if(paramaters[index] is String){ }.... // Thats just one thing i wanna use.. i've got more
..........
..........
}
return ReadInt32(0x000000);
}
so i need to figure out what type the parameter is + i wanna use an unknown amount of arguments and i have no idea how i would do this xD
I hope its clear and hopefully someone can Help me :3
Thx, Nico!
You can achieve something similar in C++ with variadic templates. Note that since C++ has no runtime reflection, it's not possible to dynamically get the type of any value: it can only be done at compile-time. Importantly, this also means that you cannot build a parameter list at runtime and pass it to the function without rolling out your own stuff to do it.
It is also arguably much more complicated than a C# equivalent (but then again, if C++ had all the strengths of C# with no weaknesses of itself, nobody would be using C#).
There may be other patterns, but the one I usually use looks like this (example with a print function):
template<typename... T>
void print_all_values(int value, T... values)
{
printf("%i ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(double value, T... values)
{
printf("%g ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(const char* value, T... values)
{
printf("%s ", value);
print_all_values(values...);
}
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
{
printf("(can't print) ");
print_all_values(values...);
}
void print_all_values() {}
print_all_values(4, "hello world", 5.2, nullptr);
// prints: "4 hello world 5.2 (can't print)"
What happens here:
template<typename... T>
void print_all_values
This tells the compiler to create a distinct version of print_all_values for each different parameter type sequences it finds in my program.
void print_all_values(int value, T... values)
void print_all_values(double value, T... values)
void print_all_values(const char* value, T... values)
These differentiate the call per the first parameter. The idea here is that the function will only print its first parameter, then recursively call the template version with the remaining parameters:
{
printf("%s ", value);
print_all_values(values...);
}
At the end of the recursion chain, each parameter has been printed.
For my example print_all_values(4, "hello world", 5.2, nullptr), this is basically what would happen:
print_all_values(4, "hello world", 5.2, nullptr) -> the compiler uses print_all_values(4, ...), at runtime it'll do printf("%i", value), and the call at the end of the function becomes:
print_all_values("hello world", 5.2, nullptr) -> the compiler uses print_all_values("hello world", ...), at runtime it'll do printf("%s", value), and then:
print_all_values(5.2, nullptr) -> the compiler uses print_all_values(5.2, ...), printf("%g", value), then:
print_all_values(5.2, nullptr) -> the compiler can't find a suitable overload, so it falls back to the print_all_values(Unknown&& value, T... values) overload, does "(can't print)", and creates a call to print_all_values(), which does nothing.
The last overload:
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
tells the compiler how handle any unknown type (in this case by printing (can't print)). Without this overload, we'd get a compile-time error if we tried to print an unknown type (because it all happens at compile-time, remember).
Did you already try a variadic template declaration like given in the following sample?
template<typename... Args>
static int32_t Procedure(uint32_t address, Args&&... parameters) {
// ...
}
C++ allows you to write functions accepting any number of parameters in the form of variadic template functions:
template<typename... ARGS>
void f( ARGS... args )
{
}
In that example, ARGS and args denote what is known as variadic packs. Neither are a template parameter or an function parameter, are just something that represents a set of template parameters, and a set of function parameters (Respectively).
So that are not parameters, are parameter packs, and then them cannot be manipulated directly. To use the content of a variadic pack, you have to expand the pack with an ellipsis.
Consider the example above: template<typename... ARGS> declares a variadic template with a variadic-pack named ARGS which represents a set of type template parameters.
In the next line, we expand that pack (ARGS...) to use that types as the types of the function argumments. That generates the variadic pack of function argumments args.
To use that argumments inside the function, you should expand args too. Since a pack is just a indetermined set of argumments, you can only use it in contexts where you use the hole set of argumments, in other words, you cannot access directly an specific element of the pack. For example:
template<typename... ARGS>
void f( ARGS... args )
{
f( args... ); //We call f() expanding the args pack of function parameters
//and passing the set of parameters to the function.
}
If you need to traverse the set of parameters in a pack (Which you would do in C# using the subscript operator on the params), you have to use the functional programming way of pattern matching and head-tail recursive list traversing:
template<typename HEAD , typename... TAIL>
void print( const HEAD& head , const TAIL&... tail )
{
std::cout << head << std::endl; //Do something with the head (Which is a
//normal function parameter)
print( tail... ); //Pass the tail to the next call
}
Note that function expects at least one parameter (A variadic template could be empty, but print() has one non-variadic parameter) . You should provide an overload with no parameters to act as base case (The case when there is no more argumments in the argumments list):
void print()
{
//Base case. Does nothing.
}
Now consider the signature of the print() function: Is a function which can take any number of parameters of any combination of types. In contrast to the C# (And Java) approach, storing the parameters in an array of an universal base class, and rely on polymorphism and casting), the C++ approach uses a statically-typed alternative, where the type of each function parameter is well determined at compile time.
I have a tuple in D. I want to apply an element-wise operation on that tuple, and get that transformed tuple for passing into another function that accepts variadic template arguments. The execution path of the transform is defined at compile time, but the actual value is not.
The purpose of this is similar to the template mechanism used in C++'s bind construct, for determining where to use placeholders/passed arguments and where to use stored arguments at compile time.
How do I accomplish this?
this is the first time in D I've ever missed a feature in C++11's template system: the pack/unpack operator - please make me not feel bad :-(
EDIT: Ended up using mixins, because apparently any generic programming solution you want can be solved by using them. May answer with them if no one comes up with anything more elegant than taking D's ridiculously powerful jackhammer-of-a-generic-programming-tool to it.
The element of a tuple can be anything that a template alias parameter can be. However, run-time expressions cannot be alias parameters - they are evaluated at compile time. Thus, it is not possible to transform a tuple using a transformation that runs at compile-time (barring workarounds such as where the transformation defines a #property function that returns the result).
If the expression and transformation can be evaluated at compile-time, see staticMap from std.typetuple.
If I understand the question right, then this is possible but it's a highly experimental (undocumented and not guaranteed to always work) feature:
import std.stdio;
import std.traits;
import std.typetuple;
ReturnType!Call Delay(alias Call, alias arg)() { return Call(arg); }
template Map(alias Call, args...)
{
static if (args.length > 1)
alias Map = TypeTuple!(Delay!(Call, args[0]),Map!(Call, args[1..$]));
else
alias Map = Delay!(Call, args[0]);
}
int square(int arg)
{
return arg * arg;
}
void print(int res1, int res2)
{
writefln("%s %s", res1, res2); // writes '25 100'
}
void test(Args...)(Args args)
{
print(Map!(square, args));
}
void main()
{
int x = 5;
int y = 10;
test(x, y);
}
Originally asked here: Mapping variadic template arguments in D
I'm wrapping the Windows API, and I wish to make error checking easy to use, and helpful. Currently, I have a global error object, with a function set to handle a new error. The set function takes four arguments: bool Error::set (const int code, const char * file, const char * const function, const int line); The function uses the file, function, and line arguments to display them in a nicely formatted message.
To ease the setting of errors, there is a macro #define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__); This way I'm able to use setError() at any time to respond to an error that an API function has set by adding it after I call that API function.
Unfortunately, this causes the code to look something like this:
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
There is also a problem with constructors:
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
As you can see, by using member initializer syntax, I'm actually limiting myself.
One way to fix this would be to wrap every API function:
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
The function portion of the error message would tell me which function originated the error. Of course, that has to be the worst possible way of dealing with this.
The solution, it seems, is to use variadic templates. The problem is, I have no idea what I'm supposed to be doing to get them working for this. I'd imagine the final code looks something like one of the following:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
I've read things on beginning variadic templates, but they've all left me clueless of how to set up something like this. Could anyone point me in the right direction?
I found the following on a similar question:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
The respondent noted that variadic templates would be a necessity to make this generic enough. It's a start, but I'm lost and grateful of any help on the matter.
I think you'll be able to make it work with this syntax:
wrap(&SomeAPIFunction, arg1, arg2);
The key is to let the compiler use type deduction to determine the template type parameters, since they get pretty messy in a hurry.
The code should look something like:
template<typename TRet, typename... TArgs>
TRet wrap( TRet(WINAPI *api)(TArgs...), TArgs... args )
{
return api(args...);
}
Naturally, you'll want to use a macro to hide the address-of-function operator, use stringizing to store the function name, and store the filename and line number also, passing all of that to the actual variadic function. You'll need variadic macros for that. In fact, could you do all of this just with variadic macros and no templates?