考虑这个功能模板:
template <class... T>
void foo (std::tuple<T, char, double> ... x);
此调用有效:
using K = std::tuple<int, char, double>;
foo ( K{1,'2',3.0}, K{4,'5',6.0}, K{7,'8',9.0} );
这个没有:
foo ( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} );
(gcc和clang都抱怨 foo
的论据太多了)
为什么第二次调用有问题?我可以重写 foo
的声明,以便第二次通话也被接受吗?
模板参数T仅用于实现可变参数 . 实际类型是已知且已修复的,只有参数的数量不同 . 在现实生活中,类型与 int, char, double
不同,这只是一个例子 .
我不能使用C 17 . 更优选C 11兼容的溶液 .
3 回答
生成一组重载的构造函数:
DEMO
生成一组重载的函数调用操作符:
DEMO 2
创建(或使用预处理器宏生成)一组重载,将参数转发给单个实现:
DEMO 3
作为数组传递并推断其大小(需要额外的一对parens):
DEMO 4
使用
std::initializer_list
作为构造函数参数(跳过额外的parens):DEMO 5
{}
不是表达式因此没有类型,参数推导关注类型,当用于执行参数推导的参数是初始化列表时,需要特别注意模板函数参数必须具有特定形式,否则参数是非 - 受到限制的背景 . 一个更简单的例子是:这由[temp.deduc.call]/1涵盖
和[temp.deduct.type]/5
当你:
显式提供模板参数,它可以工作......没有什么可推断的
将参数指定为
K{1}
,它有效...参数不再是初始化列表,是一个带有类型的表达式 .使用C 11稍微复杂一点(没有
std::index_sequence
,没有std::make_index_sequence
)但是,如果你想保持元组的可变元使用......那就是...如果你真的想要一些东西如果你接受调用模板结构的静态方法,你可以定义一个递归继承自身的模板结构,并递归地定义一个
哪里
K
是你的以下是完整的C 11编译示例
如果你可以使用C 14,你可以使用
std::make_index_sequence
和std::index_sequence
,代码变得更好,恕我直言它's a pity you can' t使用C 17,因为在你可以使用variadic
unsing
并避免所有递归继承