We can create functions with variable number of arguments using the ... notation in stdarg library. Is it also possible to pass these arguments by reference? E.g. perhaps to return a variable number of output values.
Not really (except with template varargs), for variadic functions in the sense of <stdarg.h>. You cannot call
void foo(int, ...);
as
int x = 0, y = 1;
foo(2,x,y);
and expect the x and y to be passed by reference. However, you can pass their address:
foo(2, &x, &y);
And you probably could play variadic template tricks or preprocessor macros tricks to transform FOO(x,y) into foo(2,&x,&y)
You can't with stdarg.h, but if you use c++ features you could.
I'd recommend looking into the implementation of std::tie as an example of how the standard library does this.
Related
What is/are the difference(s) between output parameters and return values? I've looked everywhere and I can't seem to find a simple definition for either.
The return value is something well defined in C++; for instance, x in return x; is the return value, whereas int in the function declaration int myfunc() is the return type.
The concpet of output paramters is not defined in C++. However someone would interpret it as either of the following:
function parameters passed by non-const reference, as long as you actually modify it in the function, otherwise why would you call it output? An example is x in the following function declaration: void myfunc(int& x);
function parameters passed by (not necessarily const) pointer to non-const, like x in both the following function declarations: void fun1(int * x) and void fun2(int * const x);
concerning this latter case, it allows "encoding" a missing parameter in as a nullptr default value, as in void fun3(int * x = nullptr).
A first difference is aesthetic: which one you like the most?
Another one is that the former concept and syntax help you convey the message that the function is giving back a value, something which is clear at the call site too (whereas at the call site you might not know if a parameter corresponding to an argument is passed by reference or not).
There are several differences between this two ways a function can have "consequences" at the caller site. For instance, you can only have one return value, whereas you can have as many paramters as you like.
Performancewise, complier optimizations can minimize the difference in performance, and maybe you should not worry (yet) about it.
I am learning c++ I am wondering if there is a way to define a template where the return type would actually be a function of the input of the function.
For example:
calling fun(1) would return me an int
calling fun(2) would return me a float
I guess this could be done using some kind of map?
1 <> int
2 <> float
The problem I was trying to solve is, for example, if I have an object called room I wanted to have a function called get_contents on which I would pass an enum to define the return type. For example:
std::vector<Table> tables = room.get_contents(Room::TABLE);
std::vector<Chair> chairs = room.get_contents(Room::CHAIR);
The first question probably isn't the best solution to this problem, nevertheless I wanted to know if it possible. Also, what is the best pattern to do what I want?
This looks to me like room.get just needs to be a template, and forget the enum.
std::vector<Table> tables = room.get<Table>();`
The language doesn't allow you to do that.
Think about it, the input for your function could be a variable, whose value is not known at compile time. The compiler won't be able to deduce the return type.
What you can do:
Use two different functions and call the appropriate one.
Have a common return type, e.g. a base class pointer or reference.
You can use templating for a function, but you will have to explicitly pass the type as the template parameter, it always has to be known at compile-time can't be inferred from the input automatically:
template <typename T>
T product(T x, T y) { x * y; }
and call it as:
product<int>(3,2);
(abstract example, may be less useful in what you are doing)
The Google C++ Style Guide draws a clear distinction (strictly followed by cpplint.py) between input parameters(→ const ref, value) and input-output or output parameters (→ non const pointers) :
Parameters to C/C++ functions are either input to the function, output
from the function, or both. Input parameters are usually values or
const references, while output and input/output parameters will be
non-const pointers.
And further :
In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers.
But I can't figure out why input/output arguments (I leave output arguments aside) should not be passed by reference. On stackoverflow there are plenty of topics related to this question : e.g. here, the accepted answer clearly say that
it's mostly about style
but that if
you want to be able to pass null, you must use a pointer
So, what's the point to always demand a pointer if I want to avoid the pointer to be null ? Why only use references for input arguments ?
The reason for demanding that output parameters are passed as pointers is simple:
It makes it clear at the call site that the argument is potentially going to be mutated:
foo(x, y); // x and y won't be mutated
bar(x, &y); // y may be mutated
When a code base evolves and undergoes incremental changes that are reviewed by people who may not know the entire context all the time, it is important to be able to understand the context and impact of a change as quickly as possible. So with this style rule, it is immediately clear whether a change introduces a mutation.
The point they are making (which I disagree with) is that say I have some function
void foo(int a, Bar* b);
If the b argument is optional, or it is unnecessary sometimes, you can call the function like so
foo(5, nullptr);
If the function was declared as
void foo(int a, Bar& b);
Then there is no way to not pass in a Bar.
This point (emphasis mine) is completely opinion-based and up to the developer's discretion.
In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers.
If I intend for b to be an output parameter, either of the following are perfectly valid and reasonable.
void foo(int a, Bar* b); // The version Google suggests
void foo(int a, Bar& b); // Reference version, also perfectly fine.
You're first question: "So, what's the point to always demand a pointer if I want to avoid the pointer to be null?"
Using a pointer announces to the caller that their variable may be modified. If I am calling foo(bar), is bar going to be modified? If I am calling foo(&bar) it's clear that the value of bar may be modified.
There are many examples of functions which take in a null indicating an optional output parameter (off the top of my head time is a good example.)
Your second question: "Why only use references for input arguments?"
Working with a reference parameter is easier than working with a pointer argument.
int foo(const int* input){
int return = *input;
while(*input < 100){
return *= *input;
(*input)++;
}
}
This code rewritten with a reference looks like:
int foo(const int& input){
int return = input;
while(input < 100){
return *= input;
input++;
}
}
You can see that using a const int& input simplifies the code.
They likely use it for consistency because they use output parameters both as references to existing memory (they're modifying previously initialized variables) and as actual outputs (the output arguments are assumed to be assigned by the function itself). For consistency, they use it as a way to more clearly indicate inputs vs. outputs.
If you never need a function/method to assign the memory of the output parameter, like returning a pointer from a lookup or allocating memory itself and returning it through a pointer, use references. If you need to do that but don't care about using pointers to act as an indication of whether a parameter is input or output, use references for output parameters when appropriate. There's no absolute requirement to use pointers in all cases unless the requirements of that function/method itself requires it.
Is it possible to create/generate a pointer declaration similar to:
void (*foo)(int, float);
bool (*foo)();
char (*foo)(char, int);
But without knowing the type of the arguments or the return type until run-time.
The function declaration would be read from a string which would specify the return and argument type (if any) then (if possible) stored in a c++ container.
Can it be done at run-time (not compile-time) ? And also C++11 can be used if necessary.
I really doubt this can be done in a statically typed language like C++ but if it can be done then what approach would someone use. No need for code (but it's appreciated) just some guidance to what must be used.
EDIT:
After testing several ideas it turns out that it can't be achieved (directly) with C++. Luckily I found the dyncall library which allows me do do it (indirectly) and on a quite large number of platforms.
Example function:
double sqrt(double x);
Using dyncall to call the function:
double r;
DCCallVM* vm = dcNewCallVM(4096);
dcMode(vm, DC_CALL_C_DEFAULT);
dcReset(vm);
dcArgDouble(vm, 4.2373);
r = dcCallDouble(vm, (DCpointer)&sqrt);
dcFree(vm);
Strings can also be used to declare the structure of a function.
C function prototype dyncall signature
void f1(); ")v"
int f2(int, int); "ii)i"
long long f3(void*); "p)L"
void f3(int**); "p)v"
double f4(int, bool, char, double, const char*); "iBcdZ)d"
It depends how many types of arguments you will handle. Technically - you can do everything in C++, just sometimes it's not as simple as you would want it to be.
You could use the delegate pattern:
class baseDelegate(){};
template<typename retT, typename paramT>
class delegate: public baseDelegate{
public:
retT (*ptr)(paramtT);
};
vector<baseDelegate*> yourDelegateList;
Since you tagged the topic as C++11, you could also use std::function, variadic templates and so on, to make it easier. The above code is just an example.
You could doe something like
void function (string &arg, …) ;
and use the variable arguments feature of C++.
You need at lest one fixed argument though.
Generally, what you are describing is not a good thing in C++ as you indicate.
For example, I have a function foo:
int foo(int a, int b)
{
return a + b;
}
I can define a function pointer:
int (*pfoo)(int, int);
But how can I do this dynamically in program?
I want a function that takes a function as a parameter, and return a function pointer that takes the same arguments and return value as a given function.
Then I can use it like this:
void* pfoo = getFuncPtrFromFunc(foo);
Which does what the code above did.
Is this possible?
You cannot do this at run-time (i.e. dynamically); remember that all types (and function pointers are types) are statically determined at compile-time.
Imagine if you could do this, and you somehow obtained a function-pointer whose type was variable (i.e. it could point to a float (*)(int,int) or a char (*)(float)). How would you ever be able to call that and provide a meaningful list of arguments?
You can, however, get this information at compile-time; one way is to use the Boost TypeTraits library.
c++ is a static typed language, and doesn't allow to do what you want.