使用参数包作为模板化 class 的类型名称

Using parameter pack as typename for a templated class

这个有效吗: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;
}

C++ 是否真的允许这样的扩展,或者这个实现是基于编译器定义的?我不相信我在其他地方看到过这种类型的语法:Container<type_pack>&...。这只是我为了实现我想要实现的目标而想出的东西,而且令人惊讶的是它有效。所以我的问题是,这是 UB,还是在标准中实际提到这是明确定义的?

为什么不呢?

在您的代码中,type_pack

template<typename T, typename...type_pack>
void fn(const Container<T>& head, const Container<type_pack>&... args)

处于推导上下文中,因此编译器可以从

推导 float,对于 type_pack...
fn(Container<int>{}, Container<float>{});

您正在指定可变数量的参数,这些参数属于 Container 类型,模板化了将用于推导 type_pack 的类型。例如,如果您调用:

fn(Container<int>{}, Container<float>{});

type_pack 将代表 float 类型。但是,如果您调用:

fn(Container<int>{}, Container<float>{}, Container<int>{}, Container<std::string>{});

type_pack代表一个float, int, std::string的参数包。

标准明确定义了此行为。