Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default parameter template vs variadic template : what is the last template parameter?

I'm a little confused because both a default parameter template and a variadic template parameter have to be the last parameter of a template. So what is the good official syntax for my function ?

template<typename T, class T2 = double, unsigned int... TDIM> myFunction(/* SOMETHING */)

or

template<typename T, unsigned int... TDIM, class T2 = double> myFunction(/* SOMETHING */)
like image 262
Vincent Avatar asked Aug 10 '12 10:08

Vincent


1 Answers

Actually, template parameter packs and default parameters don't have to be the last in a function, if anything that comes after it will be deduced (or is defaulted):

template<class T, class... Args, class T2 = int, class T3>
void f(T3){}

Note that you can never specify anything for T2, since everything will be swallowed by the variadic pack. Concluding from that, I'd say it makes sense to put variadic packs after default parameters, if they are to be manually specified. For deduced packs, it's more of a stylistic choice, and I personally would put them last.

Note that if they're deduced as part of another template, you can even have multiple variadic packs:

template<class...> struct pack{};

template<class T, class... P1, class... P2, class T2>
void f(pack<P1...>, pack<P2...>, T2){}

In cases like this, I'd put the packs and other template parameters relative to their function parameters, i.e. in the same order.

For (primary) class templates, this is different of course, since there can be no deduced arguments. In fact, variadic packs have to be at the end of the template parameter list:

template<class T, class... Args, class T2=int>
struct X{}; // error

For partial specializations, the order doesn't matter and it's a purely stylistic choice again. I personally would put them relative to the primary template's parameters, like before.

template<class T1, class T2>
struct X{};

template<template<class...> class T1, class... A1,
    template<class...> class T2, class... A2>
struct X<T1<A1...>, T2<A2...>>{};
like image 177
Xeo Avatar answered Nov 15 '22 17:11

Xeo