are these functions equivalent?
这些功能相当吗?
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));
}
if they are, can I always use this macro for perfect forwarding?
如果是,我可以一直使用这个宏来完美转发吗?
#define MY_FORWARD(var) std::forward<decltype(var)>(var)
or just use
或者只是使用
bar(std::forward(t));
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?
我相信foo2和foo3是一样的,但是我发现人们总是像foo一样使用前进,有没有理由明确写出类型?
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?
我知道T和T &&是两种不同的类型,但我认为std :: forward
Edit:
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
我想使用宏的原因是我想在下面的C ++ 1y代码上保存一些打字,我在不同的地方有很多类似的代码
#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));
};
}
1 个解决方案
#1
14
Are these functions two equivalent?
这些功能是两个相同的吗?
Yes, they are equivalent. decltype(t)
is the same as T&&
, and when used with std::forward
, there is no difference between T
and T&&
, regardless what T
is.
是的,它们是等价的。 decltype(t)与T &&相同,当与std :: forward一起使用时,T和T &&之间没有区别,无论T是什么。
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 can result in subtle errors. For example adding additional parentheses won't work:
是的你可以。如果您想使代码不可读且不可维护,那么请执行此操作。但我强烈建议不要这样做。一方面,你使用这个宏基本上没什么收获。而另一方面,其他开发人员必须查看定义才能理解它,并且可能导致细微的错误。例如,添加额外的括号将不起作用:
MY_FORWARD((t))
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:
相反,具有decltype的形式是完全有效的。特别是,它是从通用lambda表达式转发参数的首选方法,因为没有显式类型参数:
[](auto&& t) { foobar(std::forward<decltype(t)>(t)); }
I ignored the 3rd variant with std::forward(t)
, because it isn't valid.
我用std :: forward(t)忽略了第3个变种,因为它无效。
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 hand, the code becomes much cleaner:
更新:关于您的示例:您可以使用call-by-value而不是函数模板foo的call-by-reference。然后你可以使用std :: move而不是std :: forward。这为代码添加了两个额外的移动,但没有额外的复制操作。另一方面,代码变得更清晰:
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));
};
}
#1
14
Are these functions two equivalent?
这些功能是两个相同的吗?
Yes, they are equivalent. decltype(t)
is the same as T&&
, and when used with std::forward
, there is no difference between T
and T&&
, regardless what T
is.
是的,它们是等价的。 decltype(t)与T &&相同,当与std :: forward一起使用时,T和T &&之间没有区别,无论T是什么。
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 can result in subtle errors. For example adding additional parentheses won't work:
是的你可以。如果您想使代码不可读且不可维护,那么请执行此操作。但我强烈建议不要这样做。一方面,你使用这个宏基本上没什么收获。而另一方面,其他开发人员必须查看定义才能理解它,并且可能导致细微的错误。例如,添加额外的括号将不起作用:
MY_FORWARD((t))
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:
相反,具有decltype的形式是完全有效的。特别是,它是从通用lambda表达式转发参数的首选方法,因为没有显式类型参数:
[](auto&& t) { foobar(std::forward<decltype(t)>(t)); }
I ignored the 3rd variant with std::forward(t)
, because it isn't valid.
我用std :: forward(t)忽略了第3个变种,因为它无效。
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 hand, the code becomes much cleaner:
更新:关于您的示例:您可以使用call-by-value而不是函数模板foo的call-by-reference。然后你可以使用std :: move而不是std :: forward。这为代码添加了两个额外的移动,但没有额外的复制操作。另一方面,代码变得更清晰:
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));
};
}