c++ - 是否可以在`std::forward`中省略模板参数?
问题描述
的标准签名std::forward
是:
template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&) noexcept;
template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&&) noexcept;
因为参数类型不是T
直接的,所以我们应该在使用时指定模板参数std::forward
:
template<typename... Args>
void foo(Args&&... args)
{
bar(std::forward<Args>(args)...);
}
然而,有时模板参数并不像Args
. auto&&
是一个案例:
auto&& vec = foo();
bar(std::forward<decltype(vec)>(vec));
您还可以想象更复杂的模板参数类型std::forward
。无论如何,直觉上std::forward
应该知道是什么T
,但实际上并不知道。
所以我的想法是省略<Args>
,<decltype(vec)>
不管它们多么简单。这是我的实现:
#include <type_traits>
template<typename T>
std::add_rvalue_reference_t<std::enable_if_t<!std::is_lvalue_reference<T>::value, T>>
my_forward(T&& obj)
{
return std::move(obj);
}
template<typename T>
T& my_forward(T& obj)
{
return obj;
}
int main()
{
my_forward(1); // my_forward(int&&)
int i = 2;
my_forward(i); // my_forward(int&)
const int j = 3;
my_forward(j); // my_forward(const int&)
}
什么时候obj
是右值引用,例如int&&
,选择第一个重载是因为T
is int
,其is_lvalue_reference
为false;
obj
例如,当是左值引用时,const int&
选择第二个重载是因为T
isconst int&
而第一个重载是 SFINAE-ed out。
如果我的实现是可行的,为什么std::forward
仍然需要<T>
?(所以我的一定是不可行的。)
如果不是,有什么问题?还有一个问题,是否可以省略模板参数std::forward
?
解决方案
有问题的情况是当您传递右值引用类型但不属于右值值类别的东西时:
int && ir{::std::move(i)};
my_forward(ir); // my_forward(int&)
将类型传递给std::forward
将确保右值引用类型的参数将作为右值进一步移动。
推荐阅读
- php - 在 PHPUnit 测试中期望第三方静态方法调用
- c - 将 mpi 与 openMP 结合使用
- c++ - 如何在 C++ 上正确使用 getline?
- javascript - 如何从 JSON 文件中获取并显示一些图片
- css - 为什么是
- s 在显示滚动条时变得比 Firefox 中的图像更宽?
- java - 查找给定集合的幂集
- python - 有什么方法可以停止 AWS IoT Python SDK 中的记录器?
- python - 是否有 pandas 函数来获取给定单元格范围的平均值?
- microsoft-graph-api - Microsoft Graph checkMemberGroups 委派权限
- matlab - 如何在 MATLAB 中使用带有系列的 for 循环