Tho*_*tit 6 c++ templates tuples perfect-forwarding c++11
我在完美转发方面遇到了一些困难.
这是我目前的理解水平:粘合模板+右值参考+ std :: forward和一个特殊的魔法模式被激活,其中模板扣除规则与通常的含义不同,但是精心设计以允许完美转发.示例:
template <typename T>
void outer(T&& t)
{
inner(std::forward<T>(t)); // perfect forwarding activated
}
Run Code Online (Sandbox Code Playgroud)
但是,如果T实际上是一个模板化的类,会发生什么?例如,我怎样才能完善std :: tuple?如果使用T &&作为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);
}
Run Code Online (Sandbox Code Playgroud)
最后的gcc快照说:
error: cannot bind 'std::tuple<int, double, float> lvalue to
std::tuple<int, double, float>&&
Run Code Online (Sandbox Code Playgroud)
很明显,我们仍然处于一般的非模板情况,其中左值不能绑定到右值参考."完美转发模式"未激活
所以我试图偷偷摸摸地将我的元组作为模板模板传递:
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...>();
}
Run Code Online (Sandbox Code Playgroud)
但我仍然得到同样的错误.
仅当参数的类型是函数的模板类型时,完美转发才有效,因此实现完美转发的唯一方法就像第一个示例中所示:
template <typename T>
void outer(T&& t)
{
inner(std::forward<T>(t)); // perfect forwarding activated
}
Run Code Online (Sandbox Code Playgroud)
上面的方法之所以有效,是因为它是一种特殊情况,其中T被推导为SomeType&or SomeType&&。
然而,这并不意味着元组元素的类型信息会永远丢失。它仍然是可检索的(尽管我不认为你可以输入可变参数模板包)。例如,您仍然可以use_args_types_for_something_else这样调用:
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();
}
Run Code Online (Sandbox Code Playgroud)
虽然可能没有好的通用解决方案,但希望这种情况很少见。(例如,在这个特定的示例中,重载可能会更简单outer。)
| 归档时间: |
|
| 查看次数: |
1560 次 |
| 最近记录: |