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.
Related
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
}
How do I get the below code example, that compiles and works just fine to work inside a class?
Below code works just fine
#include <iostream>
using namespace std;
typedef int (*IntFunctionWithOneParameter) (int a);
int function(int a){ return a; }
int functionTimesTwo(int a){ return a*2; }
int functionDivideByTwo(int a){ return a/2; }
void main()
{
IntFunctionWithOneParameter functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo
};
for(int i = 0; i < 3; ++i)
{
cout << functions[i](8) << endl;
}
}
So the above code works fine, but I want to move it inside a class in a separate file, similar to the below NON-WORKING IDEA, where I get "incomplete type is not allowed" error at "functions[] =";
class myClass {
private:
typedef int (*IntFunctionWithOneParameter) (int a);
int function(int a){ return a; }
int functionTimesTwo(int a){ return a*2; }
int functionDivideByTwo(int a){ return a/2; }
IntFunctionWithOneParameter functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo
};
};
So my question is how can I get it to work inside my class, where it is the ONLY place the functions are needed, meaning I do need to access the functions in main() or other places!
EDIT
Here is why I need an "array of functions". To save time spent on "if's" or more exactly "switches" as I am making a software (vst) synthesizer, and the less time spent in the processing, the more notes (polyphonic) the user can play at any given time. And multiply the 44100 times per second the function is run, with 8 tone generators, which each can have up to 16 unison voices, so actually the function needed, may be called up to 5,644,800 times per second, per note played! The exact function needed inside this main loop is known BEFORE entering loop, and ONLY changes when the user adjust a knob, so I do want to avoid ifs and switches. Now had it only been one function that occasionally changes, i could just duplicate main loop with variations for each function possible, HOWEVER the main audio processing loop, has several areas, each with a variety of ever growing functions possible, each which ONLY changes when user changes various knobs. So although I could, I am not going to make 5 * 20 * 23 (and growing) different versions of a main loop, to avoid if's and switches.
There's a bunch of things wrong with the code that you posted:
No semicolon after class definition.
Class instead of class
No fixed size set for the functions member, which is not allowed. You need to explicitly set the size of the array.
Member function pointers are not the same as "regular" function pointers. Member function pointers have an implicit this as first argument, since they need an object to be invoked on. So myFunction is not of type myArrayOfFunctions. If you make myFunction and myFunction2 static, then they can be stored as regular function pointers. Is this an option?
The name myArrayOfFunctions is very confusing, since it's not an array at all.
All but the last of these will cause your code not to compile.
This example may be what you've needed.
Note: I've changed typedef statement to using and changed function's signatures to take in plain int for testing convinience sake.
class myClass {
public:
using myArrayOfFunctions = float(myClass::*)(int a, int b, float c);
float myFunction1 (int a, int b, float c)
{
return a * b * c;
}
float myFunction2 (int a, int b, float c)
{
return a + b + c;
}
myArrayOfFunctions functions[2];
myClass()
{
functions[0] = &myClass::myFunction1;
functions[1] = &myClass::myFunction2;
};
void Invoke()
{
(this->*functions[0])(1, 2, 3);
(this->*functions[1])(3, 2, 1);
}
};
int main()
{
myClass a;
a.Invoke();
(a.*(a.functions[0]))(4, 5, 6);
return 0;
}
As you see, I'm getting the pointer to the class function but to call it I need to call it with an actual object (this in invoke() function and a object in main()).
You can write this:
class myClass
{
public:
typedef float (*myArrayOfStaticFunctions) (int& a, int& b, float& c);
typedef float (myClass::*myArrayOfFunctions) (int& a, int& b, float& c);
static float myFunction1 (int& a, int& b, float& c){cout<<"myFunction1"<<endl; return 0;}
static float myFunction2 (int& a, int& b, float& c){ cout<<"myFunction2"<<endl; return 0;}
float myFunction3 (int& a, int& b, float& c){ cout<<"myFunction3"<<endl; return 0;}
float myFunction4 (int& a, int& b, float& c){ cout<<"myFunction4"<<endl; return 0;}
myArrayOfStaticFunctions StaticArrayfunctions[2];
myArrayOfFunctions Arrayfunctions[2];
myClass (){
StaticArrayfunctions [0] =myFunction1;
StaticArrayfunctions [1] =myFunction2;
Arrayfunctions [0] = &myClass::myFunction3;
Arrayfunctions [1] = &myClass::myFunction4;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
myClass m;
int a =0, b=0; float c;
m.StaticArrayfunctions[0] (a,b,c);
m.StaticArrayfunctions[1] (a,b,c);
myClass::myArrayOfFunctions func3 = m.Arrayfunctions[0];
myClass::myArrayOfFunctions func4 = m.Arrayfunctions[1];
(m.*func3)(a,b,c);
(m.*func4)(a,b,c);
return 0;
}
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)
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);
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.