Reputation: 1321
Is this valid: https://godbolt.org/z/_i9dwf
#include <typeinfo>
#include <iostream>
template<typename T>
struct Container
{
};
void fn()
{
return;
}
template<typename T, typename...type_pack>
void fn(const Container<T>& head, const Container<type_pack>&... args)
{
std::cout << "I am an " << typeid(T).name() << "\n";
fn(args...);
return;
}
int main()
{
fn(Container<int>{}, Container<float>{});
return 0;
}
Does C++ actually allow such expansions, or is this implementation defined based on compiler? I don't believe I have seen this type of syntax used elsewhere: Container<type_pack>&...
. It's just something I came up with for what I wanted to achieve, and surprisingly it works. So my question is, is this UB, or is there an actual mention in the standard that this is well-defined?
Upvotes: 1
Views: 44
Reputation: 13444
You are specifying a variable number of arguments, which are of a type Container
, templated with types that will be used for deducing type_pack
. For example, if you call:
fn(Container<int>{}, Container<float>{});
The type_pack
will represent a float
type. However, if you call:
fn(Container<int>{}, Container<float>{}, Container<int>{}, Container<std::string>{});
The type_pack
will represent a parameter pack of float, int, std::string
.
This behaviour is well defined by the standard.
Upvotes: 2
Reputation: 66230
Why not?
In your code, type_pack
template<typename T, typename...type_pack>
void fn(const Container<T>& head, const Container<type_pack>&... args)
is in deduced context, so the compiler can deduce float
, for type_pack...
, from
fn(Container<int>{}, Container<float>{});
Upvotes: 2