大括号初始化函数参数中的元组

问题描述 投票:0回答:1

有问题的主要问题是我想编写一个接受两个可变长度参数集的函数。

我决定去的抽象是模仿以下调用语法:

f({a,b,c},x,y);

如果abc都具有相同的类型,则可以使其与之一起使用

template <typename X, typename... A>
void f(std::initializer_list<X> xs, A&&... as) { . . . }

但是使用std::tuple而不是std::initializer_list的相似函数定义不允许我使用所需的语法。

template <typename... X, typename... A>
void f(const std::tuple<X...>& xs, A&&... as) { . . . }

我可以使用一些技巧来允许第一组中的类型是异构的吗?

附录:通常,我不知道X...的大小。

附录2:有人知道在std::tuple t{a,b,c}中使用括号初始化程序的技术原因,但在模板参数上下文中不知道吗?是因为在我的示例中xs没有被X...扩展?

c++ templates c++17 variadic-functions
1个回答
1
投票

不,目前无法使用所需的语法。初始化列表只能推导为均一类型的数组或std::initializer_list

这是一个特殊规则。初始化列表没有类型,根本无法推导为其他任何类型。如果函数参数不是数组或std::initializer_list,则为其指定了初始化程序列表的参数将成为非推论上下文,并且模板参数推导将忽略它。

特别是类模板参数的推导不能在函数参数中确定,以从支撑初始化列表中确定类型,因为自C ++ 17起可以在变量定义中完成。此类功能未添加到语言中。

原则上,您可以使用例如一个std::variant数组作为参数,但是只能在运行时解析为该类型,并且不太可能是您想要的。

您需要在初始化程序列表花括号中添加类型名称或函数调用,如

f(std::forward_as_tuple(a, b, c), x, y)

或者您也可以使用标签类型来指示平面参数列表中第一个包的结尾:

f(a, b, c, tag, x, y)

然后可以通过一些模板工作来检测标签。

© www.soinside.com 2019 - 2024. All rights reserved.