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; }

18th Jun 2020, 4:17 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
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; }
19th Jun 2020, 8:38 AM
Anthony Maina
Anthony Maina - avatar
+ 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 }
19th Jun 2020, 8:56 AM
Anthony Maina
Anthony Maina - avatar
+ 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. :)
18th Jun 2020, 9:35 PM
Dennis
Dennis - avatar
+ 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
19th Jun 2020, 10:32 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
+ 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.
18th Jun 2020, 4:47 PM
$¢𝐎₹𝔭!𝐨𝓝
$¢𝐎₹𝔭!𝐨𝓝 - avatar
+ 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.
18th Jun 2020, 5:15 PM
$¢𝐎₹𝔭!𝐨𝓝
$¢𝐎₹𝔭!𝐨𝓝 - avatar
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 ?
18th Jun 2020, 4:57 PM
Ketan Lalcheta
Ketan Lalcheta - avatar