对失败的元组向量使用可变参数模板参数

Using a variadic template parameter for vectors of tuples failing

我正在使用 g++ 5.2。为什么这样做有效?

void func(std::vector<std::tuple<int>> v)
{
    ...
}

func({ std::make_tuple(1), std::make_tuple(2), std::make_tuple(3) });

但这不?因为他们在逻辑上似乎等同于我。

template <typename... Args>
void func(std::vector<std::tuple<Args...>> v)
{
    ...
}

func({ std::make_tuple(1), std::make_tuple(2), std::make_tuple(3) });

它给出错误:

error: could not convert ‘{std::make_tuple(_Elements&& ...) [with _Elements = {int}](), std::make_tuple(_Elements&& ...) [with _Elements = {int}](), std::make_tuple(_Elements&& ...) [with _Elements = {int}]()}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<std::tuple<>, std::allocator<std::tuple<> > >’
func({ std::make_tuple(1), std::make_tuple(2), std::make_tuple(3) });
                                                                   ^

编译失败,因为无法从初始化列表中推导出函数模板参数。

如果您实际使用元组向量调用它们,它们的行为会有些相同,但您不这样做。

void func(std::vector<std::tuple<int>> v)

这有一个已知类型的参数,您使用的初始化列表可以转换为该类型,因此它可以工作。你说 "the function takes type X, and here is an argument convertible to X"。编译器可以做到这一点。

template <typename... Args>
void func(std::vector<std::tuple<Args...>> v)

此函数模板必须推断其参数类型。但是您不会使用允许它推断元组元素类型的元组向量来调用它。您使用可以转换为许多不同类型(向量、列表、元组或许多其他类型)的初始化列表来调用它。在将初始化列表转换为该类型之前,编译器无法推断出向量的类型,但是在知道您拥有的向量类型之前,它无法知道转换是否有效,因此存在先有鸡还是先有蛋的情况.它在进行转换之前无法推断类型,但在知道类型之前无法进行转换。