Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 完美转发和std::tuple(或其他模板类)_C++_Templates_C++11_Tuples_Perfect Forwarding - Fatal编程技术网

C++ 完美转发和std::tuple(或其他模板类)

C++ 完美转发和std::tuple(或其他模板类),c++,templates,c++11,tuples,perfect-forwarding,C++,Templates,C++11,Tuples,Perfect Forwarding,我在完美转发方面有些困难 以下是我目前的理解水平:glue Template+rvalue reference+std::forward和一个特殊的魔法模式被激活,在这个模式中,模板推断规则的含义与平常不一样,但经过精心设计,可以实现完美的转发。例如: template <typename T> void outer(T&& t) { inner(std::forward<T>(t)); // perfect forwarding activated

我在完美转发方面有些困难

以下是我目前的理解水平:glue Template+rvalue reference+std::forward和一个特殊的魔法模式被激活,在这个模式中,模板推断规则的含义与平常不一样,但经过精心设计,可以实现完美的转发。例如:

template <typename T>
void outer(T&& t)
{
   inner(std::forward<T>(t)); // perfect forwarding activated
}
模板
无效外部(T&T)
{
内部(std::forward(t));//完美转发已激活
}
但是如果T实际上是一个模板类,会发生什么呢? 例如,如何完美地转发std::tuple?如果使用T&&as aboce,我将丢失元组中包含的对象的所有类型信息。
但是,以下代码无法工作:

template <typename... Args>
void outer(std::tuple<Args...>&& t) 
{
   inner(std::forward<std::tuple<Args...>>(t));
   use_args_types_for_something_else<Args...>(); // I need to have Args available
}

int main()
{
   std::tuple<int, double, float> t(4, 5.0, 4.0f);
   outer(t);
}
模板
无效外部(标准::元组和(&t)
{
内部(标准:正向(t));
使用_args_types_for_something_else();//我需要有可用的参数
}
int main()
{
std::元组t(4,5.0,4.0f);
外部(t);
}
最后一个gcc快照显示:

error: cannot bind 'std::tuple<int, double, float> lvalue to
std::tuple<int, double, float>&&
错误:无法将'std::tuple左值绑定到
std::tuple&&
所以很明显,我们仍然处于一般的、非模板的情况下,左值不能绑定到右值引用。“完美涉水模式”未激活

所以我试着偷偷地把我的元组作为模板传递:

template <
  typename... Args
  template <typename...> class T
>
void outer(T<Args...>&& t) 
{
   inner(std::forward<T<Args...>>(t));
   use_args_type_for_something_else<Args...>(); 
}
模板<
类型名。。。Args
模板类T
>
无效外部(T&T)
{
内部(标准:正向(t));
使用参数类型表示其他内容();
}

但我仍然会遇到同样的错误。

完美转发仅在参数类型为函数的模板类型时有效,因此实现完美转发的唯一方法如第一个示例所示:

template <typename T>
void outer(T&& t)
{
   inner(std::forward<T>(t)); // perfect forwarding activated
}

虽然可能没有好的通用解决方案,但希望这种情况很少出现。(例如,在这个特定的示例中,只重载
outer
)可能更简单。

您不能在不指定类型的情况下调用std::forward吗(因为它是一个模板函数,可以使用演绎)<代码>标准::转发(t)感谢您的准确回答。因此,关于c++11中的完美转发,我仍然感到有点不安,因为它如此依赖这个奇怪的组合“template+rref+std::forward”。它创建了一个很小的点,一般规则(如“右值引用仅绑定到右值”)不再适用。我想知道一些用于完美转发的特殊语法是否对c++11更好。无论如何,这种情况下的解决方法确实没有什么大不了的,因为仍然有可能为
外部
设置两个重载,一个使用const ref,另一个使用rref来模拟PF。
template <class T>
struct call_uses_args;

template <class ...Args>
struct call_uses_args<std::tuple<Args...>>
{
    void call() const { use_args_types_for_something_else<Args...>(); }
};

template <typename TupleT>
void outer(TupleT&& t)
{
   inner(std::forward<TupleT>(t));
   call_uses_args<typename std::remove_reference<TupleT>::type>().call();
}