Any way to notate the outputs in function arguments? - c++

Lets say I have a function
void doStuff(vector<int> &a, int b, vector<int> &c> {
c = vector<int>(a.size());
for (int i = 0; i < a.size(); i++) {
c[i] = a[i] + b;
}
}
obviously, upon seeing the function, we know that "c" is the output.
For anybody who hasn't seen the function definition though, it remains a mystery unless i name c something like "output_c". Maybe I'm just being vein but I don't like naming things "ouput_xxx", is there any syntax candy for letting the user of the function know that its supposed to be the output?

Syntax, by itself, can be a guide to indicate which one is an input argument and which one is an output argument. However, an output argument can also serve as an input argument too. You cannot tell that by just looking at the signature.
Examples:
int foo(int arg); // The argument is copy by value. It can only be an input argument.
void foo(std::vector<int> const& arg); // The argument is by const&.
// It can only be an input argument.
void foo(std::vector<int>& arg); // The argument is by &. It can be:
// 1) an output argument.
// 2) an input and output argument.
// 3) an input argument (bad practice)

You could add a preprocessor directive:
#define OUT
and put it in the parameter list like so:
void doStuff(vector<int> &a, int b, OUT vector<int> &c) ...
I think I've seen some APIs do something like this. That way it is explicitly stated in the function signature but you don't have to modify the variable names. The code is also unchanged at compile time since OUT is not defined to be anything, it is just a defined symbol.
I think, though, I would rely on your own documentation when writing the function and/or return-by-value instead of doing something like this. You could also make use of the const keyword to flag a parameter that is guaranteed not to change - that's what the syntax is designed for.

Related

C++ function input argument by reference vs by pointer

I am new to C++ and have done only MATLAB earlier.
My Q is about the input argument of the following functions, which call variables by value,reference and pointer.
void SwapbyValue (int a, int b){
// Usual swapping code
}
void SwapbyRef (int &a, int &b){
// Usual swapping code
}
void SwapbyPoint(int *a,int *b){
//Usual swapping code
}
Since my Q isn't about how the above functions work but rather about how I call them, I've left out the code. So, I understand we call the above functions by typing SwapbyRef (i1,i2),SwapbyRef (i1,i2) and SwapbyPoint(&i1,&i2) when i1 and 12 are int.
That confuses me the life out of me. Okay, I get that the first function takes in values and makes sense. But in the second one, calling by just i1 and i2 doesn't make sense as when the function is defined, we set its input as &a and not just a but it still runs. Again in the third, we set the input argument as a pointer i.e. *a but we're passing an address &a (like 0x7956a69314d8) when we call it.
Why does it run when we pass the wrong kind of input to the function?
For example,a Matlab analogy,it looks like passing a char to a int function. Help!
int &a is a reference to an int, meaning, it will accept all int variables that already exist. What you cannot do is for example SwapbyRef(4, 5) using SwapbyRef (int &a, int &b), because 4 and 5 are temporary ints that do not exist somewhere in memory as variables.
Btw, you should probably just look up what a reference in c++ is. That would help you most, I think.

why is the first prototype is correct while second is incorrect?

In a question, the first prototype given below is called valid
int Function(int Tmp = Show());
while in the second case it is called as invalid declaration.Why?
float Function(int Tmp = Show(int, float));
here is the link to the question- http://www.indiabix.com/cpp-programming/functions/discussion-61
The fact that Show is being used to establish a default argument value is a red herring.
Show(int, float) doesn't make sense in the context of calling that function Show, whereas Show() does.
When you call a function in C++, you supply parameter values, not the types.
Because you don't pass any actual parameters to the Show() function in the second case. You would want something like
float Function(int Tmp = Show( 1, 2.3 ));
The first case doesn't need parameters because it is presumably a call to a function that looks like this:
int Show();

Using input argument as output

my question is:
I saw(in CUDA examples) that it is possible to use one of the input arguments of a function as output variable. Example: add two integers, c=a+b:
void function AddT(int a,int b,int c){
c=a+b;
}
But this will not work. The function will not alter the value of c in the main program. Who can I fix it and allow the function to change the value of c?
Pass the variable c by reference.
void function AddT(int a, int b, int& c)
{
c = a + b;
}
This will make it so that any changes to c that you make in the function will remain even after the function ends. My wording is pretty poor here; you can look here for more information:
Pass by Reference / Value in C++
What's the difference between passing by reference vs. passing by value?

Writing a function with an optional parameter

So I have a function with several parameters that will need to perform several tasks based on these parameters. But when I call this function I may not need it to perform some of the tasks in it.
For example my function has parameters (int x, int bin, int value) but sometimes when I call it I don't want it to evaluate the part of the function using int value. How can I accomplish this? I've heard of using optional arguments which default the argument to 0 if I don't specify it but that is not what I want. What I want is this, if I provide a value for "int value" then I want the part of my function using this value to evaluate, otherwise, ignore it.
I suggest using function overloading:
void foo(int x, int bin) {
//...
}
void foo(int x, int bin, int value) {
foo(x, bin);
// extra stuff using value...
}
But you could also make value a pointer and use nullptr to signify it shouldn't be used.
Here is another option. In this case if the function is called with only two parameters value will be initialized to a sentinel (-1 in this case) and can be checked in the code.
void foo(int x, int bin, int value=-1) {
// x stuff
// bin stuff
if (value != -1) {
// value stuff
}
}
This will only work if there is some invalid value though which could be 0, -1, or the maybe the max value of an int. Function overloading is probably a better option though.

Advantage of using default function parameter

int add (int x, int y=1)
int main ()
{
int result1 = add(5);
int result2 = add(5, 3);
result 0;
}
VS
int add (int x, int y)
int main ()
{
int result1 = add(5, 1);
int result2 = add(5, 3);
result 0;
}
What is the advantage of using the default function parameter, in term of execution speed, memory usage and etc? For beginner like me, I sometimes got confused before I realized this usage of default function parameter; isn't it coding without default function parameter made the codes easier to read?
Your add function is not a good example of how to use defaulted parameters, and you are correct that with one it is harder to read.
However, this not true for all functions. Consider std::vector::resize, which looks something like:
template<class T>
struct vector_imitation {
void resize(int new_size, T new_values=T());
};
Here, resizing without providing a value uses T(). This is a very common case, and I believe almost everyone finds the one-parameter call of resize easy enough to understand:
vector_imitation<int> v; // [] (v is empty)
v.resize(3); // [0, 0, 0] (since int() == 0)
v.resize(5, 42); // [0, 0, 0, 42, 42]
The new_value parameter is constructed even if it is never needed: when resizing to a smaller size. Thus for some functions, overloads are better than defaulted parameters. (I would include vector::resize in this category.) For example, std::getline works this way, though it has no other choice as the "default" value for the third parameter is computed from the first parameter. Something like:
template<class Stream, class String, class Delim>
Stream& getline_imitation(Stream &in, String &out, Delim delim);
template<class Stream, class String>
Stream& getline_imitation(Stream &in, String &out) {
return getline_imitation(in, out, in.widen('\n'));
}
Defaulted parameters would be more useful if you could supply named parameters to functions, but C++ doesn't make this easy. If you have encountered defaulted parameters in other languages, you'll need to keep this C++ limitation in mind. For example, imagine a function:
void f(int a=1, int b=2);
You can only use the given default value for a parameter if you also use given defaults for all later parameters, instead of being able to call, for example:
f(b=42) // hypothetical equivalent to f(a=1, b=42), but not valid C++
If there is a default value that will provide correct behavior a large amount of the time then it saves you writing code that constantly passes in the same value. It just makes things more simple than writing foo(SOME_DEFAULT) all over the place.
It has a wide variety of uses. I usually use them in class constructors:
class Container
{
// ...
public:
Container(const unsigned int InitialSize = 0)
{
// ...
}
};
This lets the user of the class do both this:
Container MyContainer; // For clarity.
And this:
Container MyContainer(10); // For functionality.
Like everything else it depends.
You can use it to make the code clearer.
void doSomething(int timeout=10)
{
// do some task with a timeout, if not specified use a reasonable default
}
Is better than having lots of magic values doSomething(10) throughout your code
But be careful using it where you should really do function overloading.
int add(int a)
{
return a+1;
}
int add(int a,int b)
{
return a+b;
}
As Ed Swangren mentioned, some functions have such parameters that tend to have the same value in most calls. In these cases this value can be specified as default value. It also helps you see the "suggested" value for this parameter.
Other case when it's useful is refractoring, when you add some functionality and a parameter for it to a function, and don't want to break the old code. For example, strlen(const char* s) computes the distance to the first \0 character in a string. You could need to look for another characted, so that you'll write a more generic version: strlen(const char* s, char c='\0'). This will reuse the code of your old strlen without breaking compatibility with old code.
The main problem of default values is that when you review or use code written by others, you may not notice this hidden parameter, so you won't know that the function is more powerful than you can see from the code.
Also, google's coding style suggests avoiding them.
A default parameter is a function parameter that has a default value provided to it. If the user does not supply a value for this parameter, the default value will be
used. If the user does supply a value for the default parameter, the user-supplied value is used.
In computer programming, a default argument is an argument to a function that a programmer is not required to specify. In most programming languages, functions may take one or more arguments. Usually, each argument must be specified in full (this is the case in the C programming language)
Advantages of using default parameter, as others have pointed out, is indeed the "clarity" it brings in the code with respect to say function overloading.
But, it is important to keep in mind the major disadvantage of using this compile-time feature of the language: the binary compatibility and default function parameter does not go hand in hand.
For this reason, it is always good to avoid using default params in your API/interfaces classes. Because, each time you change the default param to something else, your clients will need to be recompiled as well as relinked.
Symbian has some very good C++ design patterns to avoid such BC.
Default parameters are better to be avoided.
let's consider the below example
int DoThis(int a, int b = 5, int c = 6) {}
Now lets say you are using this in multiple places
Place 1: DoThis(1);
Place 2: DoThis(1,2);
Place 3: DoThis(1,2,3);
Now you wanted to add 1 more parameter to the function and it is a mandatory field (extended feature for that function).
int DoThis(int a, int x, int b =5, int c=6)
Your compiler throws error for only "Place 1". You fix that. What about other others?
Imagine what happens in a large project? It would become a nightmare to identify it's usages and updating it rightly.
Always overload:
int DoThis(int a) {}
int DoThis(int a, int b {}
int DoThis(int a, int b, int c) {}
int DoThis(int a, int b, int c, int x) {}