【问题标题】:Using a variadic template parameter for vectors of tuples failing对元组向量使用可变参数模板参数失败
【发布时间】:2015-11-14 17:22:51
【问题描述】:

我正在使用 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) });
                                                                   ^

【问题讨论】:

  • 尝试在第二次调用中删除{}。它在第一个 arg 中起作用,因为 std::vector 可以使用初始化列表进行初始化。
  • 这将调用带有三个参数的函数,它不会编译,因为它需要一个参数。
  • func({ std::make_tuple(1), std::make_tuple(2), std::make_tuple(3) }); 问题是,您如何期望编译器知道初始化列表指定vector 还是tuple
  • ...或Foo,或任何其他类型。

标签: c++ tuples variadic-templates template-meta-programming


【解决方案1】:

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

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

这有一个已知类型的参数,并且您使用的初始化器列表可以转换为该类型,因此它可以工作。您说过“函数采用 X 类型,这是一个可转换为 X 的参数”。编译器可以做到这一点。

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

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

【讨论】:

  • 但它已经是元组的初始化列表,可以匹配向量的通用签名的参数化元组,还是不匹配?
  • 哪个向量?在不知道它是什么类型的向量的情况下,如何将它与向量的可能构造函数匹配?它不是元组的std::initializer_list,它是一个花括号初始化列表,它没有类型,它是一个语法结构,而不是一个类型。该支撑初始化列表可用于初始化std::vector&lt;T&gt;::vector(intializer_list&lt;T&gt;) 构造函数的std::initializer_list&lt;T&gt; 参数,但只有在它知道T 是什么之后才能看到构造函数存在。
  • 我相信,在这种情况下,编译器推导出 floatlong 同样有效。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-10-26
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2016-12-01
    相关资源
    最近更新 更多