This question already has answers here:
Variable number of arguments in C++?
(17 answers)
Closed 8 years ago.
I want to accept some inputs for a program,the inputs are integer values.
The condition on accepting the inputs is number of inputs is not fixed
but maximum number of inputs to be taken is fixed.
for example lets say the maximum input limit is 15 inputs.
So I should be able to accept "n" inputs where "n" can have any value from 1 to 15.
Is there a way to do this in cpp?
There is a general mechanism in C and C++ for writing functions that accept an arbitrary number of arguments. Variable number of arguments in C++?. However, this will not create a restriction on the number of args or restrict the overloads to a fixed type and it is generally a bit clunky to use (IMO).
It is possible to do something with variadic templates, for instance:
#include <iostream>
#include <vector>
using namespace std;
void vfoo(const std::vector<int> &ints)
{
// Do something with the ints...
for (auto i : ints) cout << i << " ";
cout << endl;
}
template <typename...Ints>
void foo(Ints...args)
{
constexpr size_t sz = sizeof...(args);
static_assert(sz <= 15, "foo(ints...) only support up to 15 arguments"); // This is the only limit on the number of args.
vector<int> v = {args...};
vfoo(v);
}
int main() {
foo(1);
foo(1, 2, 99);
foo(1, 4, 99, 2, 5, -33, 0, 4, 23, 3, 44, 999, -43, 44, 3);
// foo(1, 4, 99, 2, 5, -33, 0, 4, 23, 3, 44, 999, -43, 44, 3, 0); // This will not compile
// You can also call the non-template version with a parameter pack directly:
vfoo({4, 3, 9});
// Downside is that errors will not be great; i.e. .this
// foo(1.0, 3, 99);
// /Users/jcrotinger/Work/CLionProjects/so_variadic_int_function/main.cpp:21:22: error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
// vector<int> v = {args...};
// ^~~~
// /Users/jcrotinger/Work/CLionProjects/so_variadic_int_function/main.cpp:38:5: note: in instantiation of function template specialization 'foo<double, int, int>' requested here
// foo(1.0, 3, 99);
// ^
return 0;
}
The static assert is the only thing that will limit this to 15 arguments. As the comment indicates, type checking is messy since the error message will come not from the function call but from the initialization of the vector.
This does require support for C++ 11's variadic templates.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am looking for an stable algorithm for rearranging the array to alternate even and odd numbers
example:
Input: {2, 8, 9 ,10 ,14 ,17 ,21, 13, 97};
Output: 9 2 17 8 21 10 13 14 97
because odd number are more than even numbers so sequencing started from first odd number 9;
also print some error message if alternate rearrangement is not possible; e.g. if some input has too much even numbers and there are not sufficient odd numbers and vice versa;
Your problem is modified version of this
Below is the solution; this might work:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> ip = {2, 8, 9 ,10 ,14 ,17 ,21, 13, 97};
std::vector<int> even, odd;
for(const auto& num: ip)
num%2 == 0 ? even.emplace_back(num) : odd.emplace_back(num); // emplace_back inserts in end maintaing stability
if(abs(even.size() - odd.size()) >1)
{
std::cout<< "\n alternate sequence not possible";
return 0;
}
auto& max = even.size() >= odd.size() ? even : odd;
auto& min = max == even ? odd : even;
ip.clear();
for(int i = 0; i< (int)min.size();i++)
{
ip.push_back(max[i]);
ip.push_back(min[i]);
}
if(max.size()> min.size())
ip.push_back(*(max.end()-1));
for(const auto& num: ip)
std::cout<<" "<< num;
return 0;
}
I know that declaring variables like this int a = 10, b = 15, c = 20 is possible and it's ok, but is it possible in any program in c++ programming language, to declare variables like this int a, b, c = 10, 15, 20 where a need to be 10, b need to be 15 and c to be 20.
Is this possible and is it right way to declare variables like this in c++?
EDIT: Is it possible with the overloading operator =?
The compiler will issue an error for such declarations
int a, b, c = 10, 15, 20;
The only idea that comes to my head is the following :)
int a, b, c = ( a = 10, b = 15, 20 );
Or you could make these names data members of a structure
struct { int a, b, c; } s = { 10, 20, 30 };
EDIT: Is it possible with the overloading operator =?
There is not used the copy asssignment operator. It is a declaration. The copy assignment operator is used with objects that are already defined.:)
int a, b, c = 10, 15, 20;
is not valid, (and even if it is it would probably initialize c to 20 (with comma operator) and let a and b uninitialized.
using c-array/std::array/std::vector may be an option:
int carray[3] = {10, 15, 20};
std::array<int, 3> a = {10, 15, 20};
std::vector<int> v = {10, 15, 20};
now we have carray[0] == a[0] && a[0] == v[0] && v[0] == 10
#include <type_traits>
#include <iostream>
using namespace std;
// Expand
#define PP_EXPAND(X) X
// Counter Arguments count
#define PP_ARG_COUNT(...) PP_EXPAND( PP_ARG_POPER(__VA_ARGS__, 5, 4, 3, 2, 1, 0) )
#define PP_ARG_COUNT2(...) PP_ARG_POPER(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
#define PP_ARG_POPER(_1, _2, _3, _4, _5, N, ...) N
int main()
{
cout << PP_ARG_COUNT(1, 2, int) << endl;
cout << PP_ARG_COUNT2(1, 2, int) << endl;
cout << PP_ARG_POPER(1, 2, int, 5, 4, 3, 2, 1 0) << endl;
return 0;
}
i have compile this code under visual studio 2013, it output:
3
1
3
why this macro need a PP_EXPAND, and PP_ARG_COUNT2 it not work well?
This is a workaround for a bug in the Visual C++ preprocessor. It incorrectly fails to expand comma-delimited token sequences in some contexts.
In your PP_ARG_COUNT2, the __VA_ARGS__ is treated as a single argument when used in the invocation of PP_ARG_POPER, causing the incorrect result.
The most common workaround for this issue is to introduce an additional layer of indirection that forces the compiler to reevaluate the comma-delimited token sequence. The technique used here, with PP_ARG_COUNT invoking through EXPAND is one way to do this; I presented a variation on this technique in an answer to another question.
This question already has answers here:
Why is this double initialization with a comma illegal?
(4 answers)
Closed 9 years ago.
Working on GCC compiler, with following two cases of operators in C program, observed different behaviors.
1.
int i = 1,2,3;
printf("%d",i); // this will give compile time error
And,
2.
int i;
i = 1,2,3;
printf("%d",i); // Its output will be 1.
In 1st case compiler gave error "error: expected identifier or ‘(’ before numeric constant".
And in second case, no errors, and output is 1.
Can anybody explain here the compiler behavior in both the cases in detail?
How does compiler interpret both statements?
Thanks in advance for your inputs.
In the first case the comma separates declaration and initialisation of several variables of the same type:
int i = 1, j = 2, k = 3;
You can add parentheses to tell the compiler it's an expression.
int i = (1, 2, 3);
If you combine them, it's easier to see why the comma is ambiguous without parentheses:
int i = (1, 2, 3), j = 4, k = 5;
In the second case the comma separates 3 expressions.
(i = 1), 2, 3
Is it possible to print a random number in C++ from a set of numbers with ONE SINGLE statement?
Let's say the set is {2, 5, 22, 55, 332}
I looked up rand() but I doubt it's possible to do in a single statement.
int numbers[] = { 2, 5, 22, 55, 332 };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
Pointlessly turning things into a single expression is practically what the ternary operator was invented for (I'm having none of litb's compound-statement trickery):
std::cout << ((rand()%5==0) ? 2 :
(rand()%4==0) ? 5 :
(rand()%3==0) ? 22 :
(rand()%2==0) ? 55 :
332
) << std::endl;
Please don't rat on me to my code reviewer.
Ah, here we go, a proper uniform distribution (assuming rand() is uniform on its range) in what you could maybe call a "single statement", at a stretch.
It's an iteration-statement, but then so is a for loop with a great big block containing multiple statements. The syntax doesn't distinguish. This actually contains two statements: the whole thing is a statement, and the whole thing excluding the for(...) part is a statement. So probably "a single statement" means a single expression-statement, which this isn't. But anyway:
// weasel #1: #define for brevity. If that's against the rules,
// it can be copy and pasted 7 times below.
#define CHUNK ((((unsigned int)RAND_MAX) + 1) / 5)
// weasel #2: for loop lets me define and use a variable in C++ (not C89)
for (unsigned int n = 5*CHUNK; n >= 5*CHUNK;)
// weasel #3: sequence point in the ternary operator
((n = rand()) < CHUNK) ? std::cout << 2 << "\n" :
(n < 2*CHUNK) ? std::cout << 5 << "\n" :
(n < 3*CHUNK) ? std::cout << 22 << "\n" :
(n < 4*CHUNK) ? std::cout << 55 << "\n" :
(n < 5*CHUNK) ? std::cout << 332 << "\n" :
(void)0;
// weasel #4: retry if we get one of the few biggest values
// that stop us distributing values evenly between 5 options.
If this is going to be the only code in the entire program, and you don't want it to return the same value every time, then you need to call srand(). Fortunately this can be fitted in. Change the first line to:
for (unsigned int n = (srand((time(0) % UINT_MAX)), 5*CHUNK); n >= 5*CHUNK;)
Now, let us never speak of this day again.
Say these numbers are in a set of size 5, all you gotta do is find a random value multiplied by 5 (to make it equi probable). Assume the rand() method returns you a random value between range 0 to 1. Multiply the same by 5 and cast it to integer you will get equiprobable values between 0 and 4. Use that to fetch from the index.
I dont know the syntax in C++. But this is how it should look
my_rand_val = my_set[(int)(rand()*arr_size)]
Here I assume rand() is a method that returns a value between 0 and 1.
Yes, it is possible. Not very intuitive but you asked for it:
#include <time.h>
#include <stdlib.h>
#include <iostream>
int main()
{
srand(time(0));
int randomNumber = ((int[]) {2, 5, 22, 55, 332})[rand() % 5];
std::cout << randomNumber << std::endl;
return 0;
}
Your "single statement" criteria is very vague. Do you mean one machine instruction, one stdlib call?
If you mean one machine instruction, the answer is no, without special hardware.
If you mean one function call, then of course it is possible. You could write a simple function to do what you want:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int setSize = 5;
int set[] = {2, 5, 22, 55, 332 };
srand( time(0) );
int number = rand() % setSize;
printf("%d %d", number, set[number]);
return 0;
}