可变参数类模板和可变参数构造函数
Variadic class template and variadic constructor
在Jason Turner的每周第48集C++有以下代码:
template<typename ... B>
struct Merged : B...
{
template <typename ... T>
Merged(T && ... t) : B(std::forward<T>(t))...
{ }
using B::operator()...;
};
它在 gcc 7.1 上失败并显示以下内容:
error: mismatched argument pack lengths while expanding 'B'
扩展 B 的正确方法是什么?
(顺便说一句,在上面的链接中,代码似乎使用一些 7.0 快照编译(。
编辑1:
如@Jarod42所述,它将使用充当函子的结构进行编译。实际视频使用lambda,它似乎在那里中断。
auto l1 = [] { return 4 ; };
auto l2 = [](const int i) { return i * 10; };
// This would work, S1, S2 are just functors structs
Merged<S1, S2> merged1(42, "hello");
// This fails
Merged merged2 = Merged(l1, l2);
编辑2:
似乎用户定义的演绎指南在这里不起作用。
template <typename ... T>
Merged(T...) -> Merged<std::decay_t<T>...>;
以上应启用以下内容:
Merged merged(l1, l2);
但事实并非如此。似乎您必须将类型传递给合并<>
Merged<t1, t2> merged(l1, l2);
这可能不是本教程想要演示的内容。
似乎
不需要在这里定义任何构造函数,而是只使用 C++17 聚合:
template<typename ... B>
struct Merged : B...
{
// This is not needed, it would actually render this class
// to be a non-aggregate one.
// template <typename ... T>
// Merged(T && ... t) : B(std::forward<T>(t))...
// { }
using B::operator()...;
};
// C++17 class deduction guidance (user defined)
template <typename ... T>
Merged(T...) -> Merged<T...>;
int main()
{
auto l1 = [] { return 4 ; };
auto l2 = [](const int i) { return i * 10; };
// Note here, using {} for initializing an aggregate
Merged merged{l1, l2};
}
请注意 C++17 类推导用户定义的指南,以及使用 {} 初始化聚合。
不需要构造函数。如果我们拥有它,这个类将不再是聚合,用于初始化的语法将停止工作。
如果参数包的大小应该相等,我们可以强制执行 std::enable_if
:
template<typename ... B>
struct Merged : B...
{
template <typename ... T,
typename = typename std::enable_if_t<sizeof...(T) == sizeof...(B)>>
Merged(T && ... t) : B(std::forward<T>(t))...
{ }
using B::operator()...;
};
这与用户定义的扣除指南一起似乎有效。
template <typename ... T>
Merged(T&& ... t) : B(std::forward<T>(t))...
{}
sizeof...(T)
应等于sizeof...(B)
:您必须按基础提供一个参数。
然后它起作用了。
如果您不提供相同数量的参数,则会出现类似于以下内容的错误:
错误:扩展"B"时参数包长度不匹配
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)