gpt4 book ai didi

c++ - 正确使用 std::result_of_t

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:14:02 30 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,我无法解决这个问题。对于此代码:

struct Foo {
int operator()() const & { return 0; }
double operator()() const && { return 0; }
};

template<typename F>
void test(F&& f)
{
static_assert<is_same<F&&, decltype(f)>::value, "!"); // (1)

// intentionally not forwarding f
using T1 = decltype(f());
using T2 = result_of_t<decltype(f)()>;
using T3 = result_of_t<F&&()>;
using T4 = result_of_t<F&()>;

static_assert(is_same<T1, T2>::value, "!"); // (2)
static_assert(is_same<T1, T3>::value, "!"); // (3)
static_assert(is_same<T1, T4>::value, "!"); // (4)
}

Foo f;
test(f); // all static_asserts passed
test(Foo{}); // (1) and (4) passed, (2) and (3) failed

因为 (1) 似乎说 decltype(f)F&& ,我猜(2)和(3)其实是一样的。那么,怎么可能decltype(f())result_of_t<decltype(f)()>不同意?为什么是decltype(f())result_of_t<F&()>一样吗?

最佳答案

对于 test(Foo{})调用decltype(f)告诉你f被声明为右值引用类型,Foo&& ,但这是它声明的类型,它不会告诉您它的值类别是什么(即右值或左值)。

在函数体内f是左值(因为它有名字),所以 decltype(f())result_of_t<F&&()> 不同

考虑:

Foo&& f = Foo{};
f();

这里也是,f被声明为右值引用类型,Foo&& ,但这并不意味着 f()调用 && - 合格的成员函数。 f是左值,所以它调用 & -合格的过载。调用 && - 限定重载你需要使用 std::move(f)()使其成为右值。

在你的test(F&&)需要使用通用引用的函数 std::forward恢复传入参数的值类别。获得与 result_of_t<decltype(f)()> 相同的类型你需要转发f恢复其原始值类别,例如

using T1 = decltype(std::forward<F>(f)());

现在它将具有与 result_of_t<decltype(f)()> 相同的类型

关于c++ - 正确使用 std::result_of_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38330163/

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