gpt4 book ai didi

c++ - 是否可以省略 `std::forward` 中的模板参数?

转载 作者:行者123 更新时间:2023-12-02 09:49:35 25 4
gpt4 key购买 nike

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&& ,选择第一个重载是因为 Tint , 谁的is_lvalue_reference是假的;

obj是左值引用,例如 const int& , 选择第二个重载是因为 Tconst int&第一个是 SFINAE 出来的。

如果我的实现是可行的,为什么是std::forward仍然需要 <T> ? (所以我的肯定是不可行的。)

如果不是,那是什么问题?还有一个问题,是否可以在 std::forward 中省略模板参数? ?

最佳答案

有问题的情况是当您传递右值引用类型但不属于右值值类别时:

int && ir{::std::move(i)};
my_forward(ir); // my_forward(int&)

将类型传递给 std::forward 将确保右值引用类型的参数将作为右值进一步移动。

关于c++ - 是否可以省略 `std::forward` 中的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61303832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com