It is also possible not to use recursion at all, but instead, deploy the package to std::initializer_list , and then insert it into the queue with the loop.
template<typename... Ts> void hash_queue(queue<size_t>& q){ std::initializer_list<size_t> hash_codes = {typeid(Ts).hash_code()...}; for(auto h : hash_codes) q.push( h ); }
Or even shorter:
template<typename... Ts> void hash_queue(queue<size_t>& q){ for(auto h : {typeid(Ts).hash_code()...}) q.push( h ); }
A longer version works even if the package is empty. In short, this is not because range-uses auto inside, which cannot infer a type from an empty initializer list.
Note that this is being queued in the reverse order compared to your sample code. (Give <int, float, double> , it first pushes int and double last, your code presses double first and int last.) If this is undesirable, use a longer form (optionally replacing std::initializer_list<size_t> with auto ) and manual cycle:
template<typename... Ts> void hash_queue(queue<size_t>& q){ std::initializer_list<size_t> hash_codes = {typeid(Ts).hash_code()...}; for(auto p = hash_codes.end(), end = hash_codes.begin(); p != end; --p) q.push( *(p-1) ); }
or in c ++ 14
template<typename... Ts> void hash_queue(queue<size_t>& q){ std::initializer_list<size_t> hash_codes = {typeid(Ts).hash_code()...}; for(auto p = rbegin(hash_codes), end = rend(hash_codes); p != end; ++p) q.push( *p ); }
source share