3
是否可以将变量函数应用于std :: apply的元组?应用std :: apply的变量函数:: apply
例如,下面的代码工作正常GCC 6.2.1:
void print_t(std::string i, std::string j) {
std::cout << i << " " << j << std::endl;
}
int main() {
std::tuple<std::string, std::string> t{"ab", "cd"};
std::experimental::apply(print_t, t);
return 0;
}
但是,如果我尝试应用可变参数函数:
template<typename T>
void vprint(T && t) {
std::cout << std::forward<T>(t) << std::endl;
}
template<typename T, typename ... Ts>
void vprint(T && t, Ts ... ts) {
std::cout << std::forward<T>(t) << " ";
vprint<Ts...>(std::forward<Ts>(ts)...);
}
int main() {
std::tuple<std::string, std::string> t{"fd", "ab"};
std::experimental::apply(vprint, t);
return 0;
}
编译器抱怨说,它不能推导出模板参数vprint
。好吧,让我们明确地写出它们:
std::experimental::apply(vprint<std::string, std::string>, t);
现在,编译器结束了一些暴露标准库内部的模糊错误。
我在C++ 11中编写了自己的std::apply
实现,并且我理解为什么它不能推导出可变参数函数模板的参数。但是,理论上,std::apply
具有所有扣除所需的信息。
那么,可变参数函数在GCC6中的应用还没有实现? C++ 17兼容的编译器是否允许这样的应用程序? 如果不是,他们会允许应用实例化的可变参数模板函数,如vprint<std::string, std::string>
?
为什么是第二方案更好? 'std :: move'基本上是对右值引用的强制转换,所以这两个代码片段的语义看起来都是相同的。 – Sergey
@Sergey:第二个继续转发参数,而第一个强制知道元组类型,可能会修改't'(因为print_t通过复制传递)。 – Jarod42
@Sergey我们假设'print_t'不是您想要调用的唯一函数;并且'std :: string &&'参数可以自由移动。你不会在你的实现中移动它。从语义上讲,在移入函数调用之后,没有人应该依赖'std :: string',但是,除非有强有力的保证(比如'get'提供)。 – Yakk