C++ Function with unlimited optional parameters and different choices of input variables - c++

Been thinking about these questions for a while now but couldn't come up with an idea on how to do it.
Lets say I have a function like:
double sum( int param1 , double param2 , [ optional... ] )
{
return param1 + param2;
}
Now I want
Q1: optional parameters
Q2: unlimited amount of optional parameters without having to declare them all ofc.
Q3: use of int and double values in those optional parameters
Thanks in advance :)

If you are familiar with c++11, there is a new concept introduced called variadic templates; which in essence allows one to create functions like you have mentioned which can take a varied amount of arguements.
The syntax for declaring such function looks like:
template <typename ... Types>
void someFunc(Types ...args) {}
Another option is to use an std::initializer_list along with std::accumulate to achieve this since you already know the types of the variables you will be using. An example using your program is this:
#include <iostream>
#include <initializer_list>
#include <numeric>
using namespace std;
double sum( initializer_list<double> vals ) {
return accumulate(vals.begin(), vals.end(), 0.0);
}
int main() {
// your code goes here
cout << sum({2, 3, 4.6, 5, 6, 74.322, 1}) << endl;
return 0;
}

You want to use Variadic function.
One example shown there is quite easy to understand, which will compute the average of an arbitrary number of arguments. Note that the function does not know the number of arguments or their types.
#include <stdarg.h>
double average(int count, ...)
{
va_list ap;
int j;
double tot = 0;
va_start(ap, count); /* Requires the last fixed parameter (to get the address) */
for(j = 0; j < count; j++)
tot += va_arg(ap, double); /* Increments ap to the next argument. */
va_end(ap);
return tot / count;
}

Related

Make the compiler deduce the parameter of a function before compilation

Here is an example of my problem.
#include <stdio.h>
//template<std::size_t A> <-- Tried to solve the problem by using template
void func1(const int power){
const int length = 1 << power;
int twoDArrayA[length][length];
for (int j = 0; j < power; j++)
{
/* Code */
}
}
int main() {
func1(4);
func1(3);
func1(2);
}
I wonder if I could somehow allow the compiler to deduce parameter power in func1 before it compiles. So instead of compiles one function, it compiles 4 functions in the format of func1 with different power value.
The reason for this is because I would like to use Vitis HLS to unroll the loop and partition the matrix so that it could be implemented onto a FPGA, where a variable-length loop or array cannot work properly.
You can do this with a template, but you've got the wrong syntax. It should be:
template<std::size_t power>
void func1(){
const std::size_t length = 1 << power;
int twoDArrayA[length][length];
...
}
int main() {
func1<4>();
...
}
Note that your variable length array (VLA) is legal C++ if length is a compile-time constant (as it is here). Nevertheless, std::array would be a better bet.
PS: Thanks for telling us why you want to do this. That was a nice touch.

va_arg will overflow in clang and apple mac os x?

#include <cstdarg>
#include <iostream>
void print(const size_t n, ...) {
va_list args;
va_start(args, n);
for (size_t i = 0; i< n; ++i ) {
auto v = va_arg(args, uint64_t);
std::cout<< v << std::endl;
}
va_end(args);
return;
}
int main() {
print(6, 1,2,3,4,5,6);
//print(5, 1,2,3,4,5);
return 0;
};
then I got the output:
 ~/private/code/cpp/trial/ ./a.out
1
2
3
4
5
140728898420742
The problem is that your print function assumes that arguments are passed as uint64_t. When you invoke the function, you however specify the values as integer literals, so the compiler will choose to pass them as int.
If you pass the numbers as 1ULL, 2ULL etc. then things should work. Or assume that the values are of type int in function print. Note that this use of va_arg. The compiler will not warn about type mismatches and you can get pretty weird behavior. For example if by accident you pass a floating point value like 1.5.
Since you are using C++, variadic templates might be better suited to your case.

Passing array by reference - subset of a larger array

I know there are other ways of implementing this or using containers. This is just to satisfy my curiosity. Suppose I have the following code:
void byref(int (&a)[5]);
int main()
{
int a[5];
byref(a);
}
An advantage of passing a C-style array by reference is that sizeof will work on it, as will std::end. But now it is only possible to pass an array of exactly this size.
Is it possible to pass a subset of a larger array to this function by reference? For example, I'd like to do:
int main()
{
int a[10];
byref(a + 1);
}
Is there any way to make this work?
I got it to build and run, giving expected values in VS2015, but of course the code looks very dodgy:
byref(reinterpret_cast<int(&)[5]>(*(a + 1)));
I have only an idea of wrapping the bad looking cast into a function:
#include <iostream>
#include <cassert>
void byref(int (&a)[5])
{
std::cout << "Hello!" << std::endl;
}
template <size_t M, class T, size_t N>
T (&subarray(T (&a)[N], size_t start))[M]
{
assert(start < N && start + M <= N);
return reinterpret_cast<T(&)[M]>(a[start]);
}
int main()
{
int a[5], b[8];
byref(a);
byref(subarray<5>(subarray<6>(b, 0), 1));
}
With this prototype, I fail to see another way to proceed than casting.
Typically, I see this one too: byref((int(&)[5])*(b + 5));, but of course it's the same and less safe than yours.
So, I don't see any clear and pretty way to do it (except for a macro maybe). I will upvote your question however, in order to see if you are missing something here!

xcode is not showing the output

I tried several time to find where is the problem, but I can not find any thing.So, could anyone help me to find the problem and why I can not see a result?
It might seem stupid question, but I new to programming world :)
This is my code :
#include <iostream>
using namespace std;
// There is the declraction of all functions
float max();
float min();
// This is the main program
int main ( int argc, char ** argv )
{
// Here you can find max
max(504.50,70.33);
// Here you can find min
min(55.77, 80.12);
return 0;
}
// This is the max function
int max(float a, float b){
float theMax;
if (a>b) {
theMax = a;
cout <<theMax ;
}
else{
theMax = b;
cout << b;
}
return theMax;
}
// This is the min function
int min( float c, float d){
float theMin;
if (c >d ) {
theMin =c;
cout << theMin;
}
else {
theMin =d;
cout << theMin;
}
return theMin;
}
You're calling std::max and std::min. That's because you wrote using namespace std, and did not declare your own min and max prior to using them. (You did declare two other min and max functions, but those take zero arguments, not two). So, when the compiler sees max(504.50,70.33); the only candidate is std::max.
You declare these overloads:
float max();
float min();
which are functions that take no arguments and return float.
You're calling
max(504.50,70.33);
and
min(55.77, 80.12);
which are functions that takes two doubles and may or may not return anything.
These match std::max and std::min, not the prototypes you declared.
You then define
int min( float c, float d){
which also doesn't match the prototypes you declared.
In other words, these functions are unknown in main, and the functions that are actually called are std::min and std::max.
Don't use using namespace std; - what you save in typing is lost in clarity and debugging.
You should also rename the functions - it's not a good idea to reuse standard library names.

Defining Exponential Preprocessor Macro

I'm planning on competing in a programming competition in a few months, and I want to define some macros to minimize the typing i need to do. Raising a number to a power is common enough to benefit from this I've been told. I only need it to work with integer arguments (though the arguments themselves may be expressions). I've tried a few different variations but I can't get the correct syntax.
/* c is where the result is stored */
#define EXP(a,b,c) c=a; for (int ii=0; ii<(b)-1; c*=(a), ii++);
This works but i can't use EXP(a,b,c) in an expression like function( EXP(a,b,c) ); I'd have to do
int result;
EXP(a,b,result);
function(result);
This, I think would work inside expressions but it fails to compile
#define EXP(a,b) int c=a; for (int ii=0; ii<(b)-1; (c)*=(a), i++); c
with: error: expected primary-expression before ‘int’ when used in:
int result = EXP(2,10);
this is my representative function:
int EXP(int base, int power) {
int result = base;
for (int ii=0; ii<power-1; ii++)
result *= base;
return result;
}
Using a macro function is the wrong tool for the job. Nevertheless, you say you think it would work inside expressions, consider how would that look for the actual compiler once the preprocessor did his work:
int result = int c=2; for (int ii=0; ii<(10)-1; (c)*=(2), i++); c
No matter how hard you try, you can't do variable definitions nor for loops within an expression.
You could use a recursive template template approach:
template<int base, unsigned int exp>
struct Pow {
enum { value = base * power<base, exp-1>::value };
};
// stopping condition
template<int base>
struct Pow<base,0> {
enum { value = 1 };
};
and use it like this:
int i = Pow<10,2>::value;