问题描述
我有一个函数,理想情况下应该看起来像这样:
template<typename... t_buffers,t_function function>
void iterate_buffers(t_buffers &&... buffers,t_function &&function);
但是,除非推导出参数包类型,否则无法推断出它,因此我的函数签名如下:
template<typename... t_buffers_and_function>
void iterate_bufferes(t_buffers_and_function &&... buffers_and_function);
然后将参数重新排列,以便该函数排在最前面。为了执行这种改组,我使用的是here中描述的技术,但是在尝试转发元组时遇到了一个问题。
这是一个有问题的简化示例:
template<typename... t_args>
void inner(std::tuple<t_args &&...> args) {};
template<typename... t_args>
void outer(t_args &&... args) {
inner(std::forward_as_tuple(std::forward<t_args>(args)...));
}
如果我传递右值(例如,通过调用outer(1,2);
),它将按预期运行。但是,如果我改为传递左值(int x = 1; int y = 2; outer(x,y);
),则会收到以下语法错误:
error: could not convert ‘std::forward_as_tuple(_Elements&& ...) [with _Elements = {int&,int&}]((* & std::forward<int&>((* & args#1))))’ from ‘std::tuple<int&,int&>’ to ‘std::tuple<int&&,int&&>’
inner(std::forward_as_tuple(std::forward<t_args>(args)...));
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
因此forward_as_tuple
产生了一个左值引用std::tuple<int&,int&>
的元组,因为提供给outer
的值是左值。 inner
是否使用转发引用,因此std::tuple<t_args &&...> args
不应该接受rvalue或lvalues的元组吗?为什么抱怨无法转换为右值?是否在这种情况下不允许转发引用(因为args并非简单地为T &&
),所以args
被强制为仅是rvalue的元组? (我在网上找到的示例似乎使用std::tuple<t_args &&...>
语法。)
如果我从inner
:void inner(std::tuple<t_args...> args)
中删除转发引用的使用,该错误就会消失。然后,如果我将左值传递给args
,则std::tuple<int&,int&>
的类型为outer
,如果我传递了右值,则类型为std::tuple<int&&,int&&>
。也许这里不需要转发引用,因为正确的左值/右值类型已经被编码到元组中,不需要转发吗?我很困惑,因为我在网上看到的所有示例(包括我链接的示例)都使用具有转发参考的inner
的原始呼叫签名。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)