Passing a single argument to a multi argument function - c++

I have a variable let say int c in a given function. I want to pass it to the other class.let say it is
function(int a, int b, int c);
I want only to pass the third argument while ignore the first two.
i.e. : I just want to pass int c, as function (c) and it just pass it to the third argument. I don't want to pass it like function(0,0,c); .. Is there any possibility. Please advise.

Looks like you want to do function overloading. Something like this-
function(int a, int b, int c);
function(int c);
inside second function you can call first function with appropriate values for a and b

You can have default values for your function:
void function(int c, int a = 0, int b = 0);
or you can overload your function:
void function(int a, int b, int c) {
//implementation 1
}
void function(int c) {
function(0, 0, c);
}
You could in both cases use it like this:
function(c);
Note : when we use default values, in function definition the argument with default values must be the last in order for example :
void function(int a = 0, int b = 0, int c)
is not a valid format.

When you have the situation where function(c) is equivalent to function(0, 0, c), it sounds like a poor design. Normally, you can use default argument values for the parameters starting from the end. It would make sense if function(c) were equivalent to function(c, 0, 0).
You can accomplish that easily by declaring the function as:
void function(int c, int a = 0, int b = 0);
I realize that you can accomplish your goal by overloading function as:
void function(int c)
{
function(0, 0, c);
}
but it still appears to be a poor interface to me.

Imho already with three parameters it is worth to structure them
struct foo {
int a;
int b;
int c;
};
allowing to have a nicer function interface
void function(foo f);
How does this help? You can provide a default constructor and let the user set only those fields that are not default:
struct foo {
int a;
int b;
int c;
foo() : a(0),b(0),c(0) {}
};
foo f;
f.b = 12;
f.c = 32;
function(f);
Now any combination of default / non-defaults is possible.
One could argue that the struct isnt really necessary and the problem is just shifted to the constructor of foo or the need to correctly set the members, but I think this is a valid approach that was missing from the other answers. (btw I am not claiming that my example here demonstrates best pratice, but the details would matter on the exact use case)

Related

Best way to make both a compile-time and runtime version of a function

I have a function that will be called by both compile-time and runtime functions (gtest and python ctypes). I need a templated version and one with the templated variables as function parameters. For example
template<int A, int B, int C>
void function_compiletime(int a, int b, int c) {
// code section 1
}
void function_runtime(int a, int b, int c, int A, int B, int C) {
// code section 2
}
Where // code section 1 is identical to // code section 2. I am cautious that I might accidentally alter something in // code section 1 and not in // code section 2. How can enforce that the body of the functions should be identical?
Best way to make both a compile-time and runtime version of a function
How can enforce that the body of the functions should be identical?
By defining a single constexpr function:
constexpr void
function_runtime(int a, int b, int c, int A, int B, int C)
{
// code section
}

Is it possible to "trick" a function take one argument when it is expecting multiple in C++?

I am looking at the "dlib"-library, more specifically the "find_min" function which is used for "optimization" (http://dlib.net/optimization_ex.cpp.html). The "find_min" function let you pass your own function as an argument, but your own function needs to take only one argument. However the function I need to pass has too many arguments (7 actually), but I need them.
So my question is this:
Is there a way to "compress" my arguments so it seems like only one, or maybe a way to change a function so it only takes one argument, but still gets all the arguments that is needed in some other smart way?
Say you've got this function:
int seven_args(int a, char b, double c, int d, int e, int f, int g) {
...
}
Stuff all the arguments into a struct and make a wrapper function that takes a single struct argument:
struct seven_args_arguments {
int a;
char b;
double c;
int d;
int e;
int f;
int g;
}
int wrapper(seven_args_arguments args) {
return seven_args(args.a, args.b, args.c, args.d, args.e, args.f, args.g);
}
You can define a structure that that contains all your arguments and make the function take a pointer to that structure as its sole argument.
Example:
Struct MyStruct {int param1; double param2; char param3;}
void MyFunction(const MyStruct* p) {......}
To invoke the function:
MyStruct params { 1, 2.5, 'c'};
MyFunction(&params);
Notice if all your parameters are of the same type, you could even better use a vector without the need to define a structure.

Ignore reference function argument

I have function with this signature (I can not edit it):
void foo(int a,int b, int& c);
I want to call it but I do not care about the getting c. Currently I do this:
int temp;
foo(5,4,temp);
//temp never used again
My solution seems dumb. What is the standard way to ignore this argument.
There is none.
If your main concern is about polluting the current stack with a temp variable, a wrapper function like this should suffice:
void foo_wrapper(int a, int b)
{
int temp; foo(a, b, temp);
}
I would write an overload that turns the output argument into a normal return value. I really don't like output arguments and think that they should be avoided.
int foo(int a, int b) {
int tmp = 0;
foo(a,b, tmp);
return tmp;
}
In your program, you just this overload and either ignore the return value or use it.
This is an over engineered solution, so I don't actually recommend it as the first option in production code.
You can create a class to help you easily ignore these kinds of arguments:
template <class T>
struct RefIgnore
{
static inline T ignored_{};
constexpr operator T&() const
{
return ignored_;
}
};
template <class T>
constexpr RefIgnore<T> ref_ignore{};
void foo(int a,int b, int& c);
auto test()
{
foo(2, 3, ref_ignore<int>);
}
Instead of reference you can pass it as a pointer
void foo(int a,int b, int *c = NULL);
in calling place you can either have it as
foo(5, 6);
or if you want to pass the 3rd argument then you can have it as
int n = 3;
foo (1, 2, &n);

How to pass optional parameter to a method in C++?

How to pass optional parameters to a method in C++ ?
is there a way like in C# we can use this statement Func(identifier:value) which allow me to pass value to any parameter i want .... for example:
//C# Code
void func(int a=4,int b,int c)
{
int sum=a+b+c;
Console.Write(sum);
}
void Main(){ func(b:5,c:6);}
In C++, default arguments have to go last, so you would write:
void func(int b, int c, int a=4)
{
int sum = a+b+c;
std::cout << sum;
}
int main() {
func(5, 6); // b = 5, c = 6, a uses the default of 4
}
You cannot provide named parameters all the call site the way you can in C# or Python. There is a boost library to fake support for naming parameters, but I've never used it.
Yes, but, short answer is that a parameter with a default value cannot precede parameters which don't get defaults. So:
void func(int a=4,int b,int c) {} //doesn't work
void func(int b, int c, int a = 4){} //works
See http://en.cppreference.com/w/cpp/language/default_arguments for more information
Yes, but you can only do it to the rightmost elements. So you could write void func(int a, int b, int c=4) or void func(int a, int b=2, int c=4) or even void func(int a=1, int b=2, int c=4), but not the example you gave.

Can I set a default argument from a previous argument?

Is it possible to use previous arguments in a functions parameter list as the default value for later arguments in the parameter list? For instance,
void f( int a, int b = a, int c = b );
If this is possible, are there any rules of use?
The answer is no, you can't. You could get the behaviour you want using overloads:
void f(int a, int b, int c);
inline void f(int a, int b) { f(a,b,b); }
inline void f(int a) { f(a,a,a); }
As for the last question, C doesn't allow default parameters at all.
No, that is not legal C++. This is specified in section 8.3.6/9 of the C++ Standard:
Default arguments are evaluated each
time the function is called. The
order of evaluation of function arguments
is unspecified. Consequently,
parameters of a function shall not be
used in default argument expressions,
even if they are not evaluated.
and:
int f(int a, int b = a); // error:
parameter a used as default argument
And C89 at least does not support default parameter values.
As a potential workaround, you could do:
const int defaultValue = -999; // or something similar
void f( int a, int b = defaultValue, int c = defaultValue )
{
if (b == defaultValue) { b = a; }
if (c == defaultValue) { c = b; }
//...
}
This is not possible
No, you cannot do that.You will surely get an error "Local variable may not appear in this context".
Your first idea might be to do something like this :
void something(int a, int b=-1, int c=-1){
if(b == -1)
b = a;
if(c == -1)
c = b;
}
I used -1 because this function only works with positive values. But what if someone uses my class and makes a mistake which ends up sending -1 to the method? It would still compile and execute, but the result would be unpredictable for the user. So the smart thing to do would be to remove any default argument and instead make a bunch of methods with the same name like this:
void something(int a, int b, int c){
/* Do something with a, b and c */
}
void something(int a){
something(a, a, a);
}
void something(int a, int b){
something(a, b, b);
}
It doesn't really take much longer to code, and if someone uses it in a programming interface with auto-complete features, it will show the 3 possible prototypes.
I do not think you can do that as that is an illegal syntax. But however, consult the C99 standard in pdf format (n1136.pdf).
However, you may get around this by using static as in declaring the variables static and using them within the function f
static int global_a;
/* In some other spot where you are calling f(), do this beforehand */
/* global_a = 4; f(); */
void f(void){
int a = global_a;
b = c = a;
/* ..... */
}
Kudos to Michael Burr for pointing out my error! :)
It sounds like you need to rethink your code and change it around for something like that.