是std :: forward< T>之间的任何差异。和std :: forward< decltype(t)> [英] is any difference between std::forward<T> and std::forward<decltype(t)>?

查看:166
本文介绍了是std :: forward< T>之间的任何差异。和std :: forward< decltype(t)>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些功能是否等同?

template <class T>
void foo(T && t)
{
    bar(std::forward<T>(t));
}

template <class T>
void foo2(T && t)
{
    bar(std::forward<decltype(t)>(t));
}

template <class T>
void foo3(T && t)
{
    bar(std::forward(t));
}

如果是,我可以始终使用此宏进行完美转发吗? p>

if they are, can I always use this macro for perfect forwarding?

#define MY_FORWARD(var) std::forward<decltype(var)>(var)

或只使用

bar(std::forward(t));

我相信 foo2 foo3 是相同的,但我发现人们总是使用向前的 foo ,是任何理由明确写入类型?

I believe foo2 and foo3 are same, but I found people are always use forward like foo, is any reason to explicitly write the type?

我理解 T T&& 是两种不同类型,但我认为 std :: forward< T> std :: forward< T&&>给出相同的结果?

I understand that T and T&& are two different types, but I think std::forward<T> and std::forward<T&&> always give the same result?

编辑:

是我想保存一些打字下面的C ++ 1y代码,我有很多类似的代码在不同的地方

the reason I want to use macro is I want to save some typing on following C++1y code, I have many similar code in different places

#define XLC_FORWARD_CAPTURE(var) var(std::forward<decltype(var)>(var))
#define XLC_MOVE_CAPTURE(var) var(std::move(var))

template <class T, class U>
auto foo(T && func, U && para )
{
    auto val = // some calculation
    return [XLC_FORWARD_CAPTURE(func),
            XLC_FORWARD_CAPTURE(para),
            XLC_MOVE_CAPTURE(val)](){
              // some code use val
              func(std::forward<U>(para)); 
          };
}


推荐答案


这两个功能两个是否等价?

decltype(t) T&&& 相同,如果 std :: forward ,在 T T&& 之间没有区别 T 是。

Yes, they are equivalent. decltype(t) is the same as T&&, and in case of std::forward, there is no difference between T and T&&, regardless what T is.


我可以始终使用此宏进行完美转发吗? / p>

Can I always use this macro for perfect forwarding?

是的,可以。如果你想让你的代码不可读和不可维护,那么这样做。但我强烈反对它。一方面,你基本上没有使用这个宏。另一方面,其他开发人员必须看看定义来理解它,并且它产生了潜在的微妙错误。例如,添加额外的括号不起作用:

Yes, you can. If you want to make your code unreadable and unmaintainable, then do so. But I strongly advise against it. On the one hand, you gain basically nothing from using this macro. And on the other hand, other developers have to take a look at the definition to understand it, and it creates a potential for subtle errors. For example adding additional parentheses won't work:

MY_FORWARD((t))

相反, decltype 的形式是完全有效的。特别是,它是从通用lambda表达式转发参数的首选方式,因为没有显式类型参数:

In contrast, the form with decltype is perfectly valid. In particular, it is the preferred way of forwarding parameters from generic lambda expressions, because there are no explicit type parameters:

[](auto&& t) { foobar(std::forward<decltype(t)>(t)); }






$ c> std :: forward(t),因为它无效。

更新:关于您的示例:您可以使用 call-by-value 而不是 call-by-reference $ c> foo 。然后可以使用 std :: move 而不是 std :: forward 。这会向代码添加两个额外的移动,但不会执行其他复制操作。另一方面,代码变得更干净:

Update: Regarding your example: You can use call-by-value instead of call-by-reference for the function template foo. Then you can use std::move instead of std::forward. This adds two additional moves to the code, but no additional copy operations. On the other side, the code becomes much cleaner:

template <class T, class U>
auto foo(T func, U para)
{
    auto val = // some calculation
    return [func=std::move(func),para=std::move(para),val=std::move(val)] {
        // some code use val
        func(std::move(para)); 
    };
}

这篇关于是std :: forward&lt; T&gt;之间的任何差异。和std :: forward&lt; decltype(t)&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆