gpt4 book ai didi

c++ - std::apply forward parameters 如何在没有显式 std::forward 的情况下应用?

转载 作者:可可西里 更新时间:2023-11-01 16:37:20 29 4
gpt4 key购买 nike

考虑 std::apply 的可能实现:

namespace detail {
template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence<I...>)
{
return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
} // namespace detail

template <class F, class Tuple>
constexpr decltype(auto) apply(F &&f, Tuple &&t)
{
return detail::apply_impl(
std::forward<F>(f), std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{});
}

为什么调用函数(f)时我们不需要执行 t 参数元组传递(std::forward)在元组的每个元素上 std::get<I>(std::forward<Tuple>(t))...在实现中?

最佳答案

你不需要 std::forward每个元素因为 std::get为元组的右值引用和左值引用重载。

std::forward<Tuple>(t)会给你一个左值( Tuple & )或一个右值( Tuple && ),并且取决于你得到什么, std::get会给你一个T & (左值)或 T && (右值)。查看 std::get 的各种重载.


关于 std::tuple 的一些细节和 std::get -

StoryTeller 所述,元组的每个成员都是左值,无论它是从右值还是左值构造的,在这里都无关紧要:

double a{0.0};
auto t1 = std::make_tuple(int(), a);
auto t2 = std::make_tuple(int(), double());

问题是——元组是右值吗?如果是,你可以移动它的成员,如果不是,你必须做一个拷贝,但是std::get已经通过返回具有相应类别的成员来解决这个问题。

decltype(auto) a1 = std::get<0>(t1);
decltype(auto) a2 = std::get<0>(std::move(t1));

static_assert(std::is_same<decltype(a1), int&>{}, "");
static_assert(std::is_same<decltype(a2), int&&>{}, "");

回到一个具体的例子 std::forward :

template <typename Tuple>
void f(Tuple &&tuple) { // tuple is a forwarding reference
decltype(auto) a = std::get<0>(std::forward<Tuple>(tuple));
}

f(std::make_tuple(int())); // Call f<std::tuple<int>>(std::tuple<int>&&);
std::tuple<int> t1;
f(t1); // Call f<std::tuple<int>&>(std::tuple<int>&);

在第一次调用f , a 的类型将是 int&&因为tuple将作为 std::tuple<int>&& 转发,而在第二种情况下,它的类型将是 int&因为tuple将作为 std::tuple<int>& 转发.

关于c++ - std::apply forward parameters 如何在没有显式 std::forward 的情况下应用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41260680/

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