So let's say we have the following code:
#include <stack>
template<class... Args>
auto make_stack(Args&&... args)
{
std::stack<INSERT_TYPE_HERE> s;
return s;
}
int main()
{
auto s = make_stack(1, 2.2, 3); //would be std::stack<double>
auto s2 = make_stack(1l, 2, 3); //would be std::stack<long>
}
How would I find the common type of the arguments in the parameter pack?
A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). A function parameter pack is a function parameter that accepts zero or more function arguments.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.
Parameter packs can only be expanded in a strictly-defined list of contexts, and operator , is not one of them. In other words, it's not possible to use pack expansion to generate an expression consisting of a series of subexpressions delimited by operator , .
Use std::common_type
from <type_traits>
. It is a type trait that provides the common type all types can be converted to. So in your case you'd need:
template<typename... Args>
auto make_stack(Args&&... args)
{
using commonT = std::common_type_t<Args...>;
std::stack<commonT> s;
return s;
}
EDIT As @DietmarKühl mentioned in the comment, you may want to use a std::decay
on commonT
if you use C++11 and not C++14. It looks like the std::decay
is applied on the resulting type only since C++14.
Unfortunately, there are no guarantees that the types are the same.
You can use std::common_type
, but be aware that (from the documentation):
Determines the common type among all types T..., that is the type all T... can be implicitly converted to.
This means that it could be not the one that you expect it to be.
Anyway, by looking at your example, it looks to me that your problem can be easily solved by means of a templated function like the one below and the use of an initializer_list
.
It follows a working example:
#include <initializer_list>
#include <stack>
template<typename T>
auto make_stack(std::initializer_list<T> list)
{
std::stack<T> s;
return s;
}
int main()
{
auto s = make_stack<double>({1, 2.2, 3}); //would be std::stack<double>
auto s2 = make_stack<long int>({1l, 2, 3}); //would be std::stack<long>
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With