gpt4 book ai didi

c++ - 为什么模板化的右值引用接受左值?

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

我看到了类似的用法

#include <iostream>
#include <functional>
using namespace std;

template<typename FN>
void Foo(FN&& Fn)
{
Fn();
}


void b()
{
cout << "2." << endl;
}

int main()
{
Foo([](){ cout << "1." << endl; });
Foo(&b);

auto c = []() { cout << "3." << endl; };

Foo(c);

std::function<void(void)> d = c;

Foo(d);

return 0;
}

我相当确定“c”是左值,但我可以相信存在一些 lambda 类型推导恶作剧。但我几乎 100% 肯定,d 是一个左值。

如果函数接受一个右值,但 d 是一个左值,为什么模板化的东西可以工作?

此外,为什么一个人会这样写 Foo 的签名而不是仅仅

template<typename FN>
void Foo(FN Fn)

最佳答案

T&&的扣除规则很棘手。

它们的设计目的是推导 T&& “转发引用”(或“通用引用”)。

首先,引用崩溃。假设你有一个未知的类型 X。现在 X没有推导。

然后如果我们检查以下类型的变量:

typedef X x0;
typedef X& x1;
typedef X const& x2;
typedef X&& x3;

然后我们设置X成为int中的一员, int& , int const&int&& ,我们得到:

X is --->  int         int&      int const&      int&&
X int int& int const& int&&
X& int& int& int const& int&
X const& int const& int& int const& int&
X&& int&& int& int const& int&&

live example .

下一位是推导规则。如果你通过 X&T&&在推导的上下文中,T推导为 X& .这导致 T&&成为X&通过上述引用折叠规则。 X const& 也会发生类似的事情.

如果你通过 X&&T&& ,它推导出T成为X . T&&变成 X&&

在他们两个之间,在推导的上下文中,template<class T> void foo(T&&t)是通用引用(好吧,现在称为转发引用)。

可以恢复t的r/l值类别与 std::forward<T>(t) ,因此得名转发引用。

这允许一个模板处理 l 和 r 值,并使用 std::forward如果您愿意,类似机器的行为会略有不同。

只有处理右值需要额外的工作:您必须使用 SFINAE 或其他重载(可能使用 =delete )。只有处理左值很容易(只需用 T& 推导)。

关于c++ - 为什么模板化的右值引用接受左值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33266782/

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