0
Variadic template is only option ?
Hi As we know, variadic template help us to have variable number of arguments... Is it necessary to implement template function only ? I need variable number of arguments for int data type only... Does below code have some missing or is it not at all allowed ? int add(int a) { return a; } int add(int a,int... values) { int sum = 0; sum += add(a); sum += add(values...); return sum; }
7 ответов
+ 3
You'll have to use templates to use in order for you to utilize parameter packs.
I think you also have to use a template class since you cannot partially specialize a template function.E.g
template<int n,int...N>
struct add{
static constexpr int value=n+add<N...>::value;
};
template<int n>//base case
struct add<n>{
static constexpr int value=n;
};
int main(){
cout<<add<1,2,3>::value;
}
+ 3
The method above requires constant expressions as arguments.If you wanted a normal function that will execute at runtime then you'll have to verify first that the type of all the arguments is int using enable_if
I.e.
int sum;
template<typename Arg,typename...Args>
typename enable_if<
is_same<int,Arg>::value,void>::type
Add(Arg a,Args...args)
{sum+=a;
Add(args...);//initiate recursion
}
template<>//base case
void
Add(int a)
{sum+=a;}
int main(){
Add(1,2,3,4,5);
cout<<sum;//outputs 15
}
+ 2
You can do type checking with C++ variadic templates.
In C++17 you can use fold expressions
https://en.cppreference.com/w/cpp/language/fold
Here is how you would use it:
template<typename... Args>
int add( int first, Args... args )
{
static_assert( ( std::is_same<int, Args>::value && ... ) );
return ( first + ... + args );
}
Static assert just does a compile time check on each type to check if it's an int or not and it will fail to compile if any of them isn't.
In C++11 you'd do something like this:
template<typename ReturnType, typename...>
struct O
{
using type = ReturnType;
};
template<typename...>
struct are_same : std::true_type
{
};
template<typename T, typename F, typename... Args>
struct are_same<T, F, Args...> : std::integral_constant<bool, std::is_same<T,F>::value && are_same<T, Args...>::value>
{
};
int add( int n ){ return n; }
template<typename... Args>
typename O<int, typename std::enable_if<are_same<int, Args>::value>::type...>::type add( int first, Args... args )
{
return first + add( args... );
}
The add return value just stores the return type while doing a compile time check on the variable types.
We can't put it in the template nor the argument list because of the typename... which has to be last.
Can't put it in front either because it wouldn't know about it Args.
Which only leaves in the return type. :)
+ 2
Thanks a lot guys. It is really helpful. along with all these suggestions, we can have a initializer_list for this problem as below:
https://code.sololearn.com/cxWypzOcAIZC
+ 1
Variadic template name itself suggest you need to use template there.
But in your case you can use variadic functions from <cstdarg> header.
The code you did is not allowed, I think.
+ 1
My bad. I think you can still use Variadic template specialization. Variadic functions are from c but that does not have any issues. For better choice you can do benchmarking.
0
Is it not from c and having issues ? I mean is variadic function still a better choice? Can we do something like define a variadic template and block all other type (in one go) and allow only one type which is allowed ?