【问题标题】:What is an rvalue reference to function type?什么是函数类型的右值引用?
【发布时间】:2011-08-10 19:42:17
【问题描述】:

我最近围绕 C++0x 的 glvalues、xvalues 和 prvalues 以及右值引用的概念展开了思考。但是,我仍然无法理解一件事:

什么是“函数类型的右值引用”?它在草案中被多次提及。为什么要引入这样一个概念?它有什么用途?

【问题讨论】:

  • 你终于明白答案了吗?我在答案下留下了评论,所以如果您知道澄清,请提供。谢谢

标签: c++11 rvalue-reference


【解决方案1】:

我讨厌循环,但是对函数类型的右值引用是对函数类型的右值引用。有一个函数类型这样的东西,例如void ()。并且你可以形成一个对它的右值引用。

N3055引入的分类系统而言,它是一个xvalue。

它的用途很少见且晦涩难懂,但并非没有用处。例如:

void f() {}
...
auto x = std::ref(f);

x 有类型:

std::reference_wrapper<void ()>

如果您查看reference_wrapper 的概要,它包括:

reference_wrapper(T&) noexcept;
reference_wrapper(T&&) = delete; // do not bind to temporary objects

在此示例中,T 是函数类型 void ()。因此,第二个声明形成了对函数类型的右值引用,目的是确保不能使用右值参数构造 reference_wrapper。即使T 是常量也不会。

如果形成对函数的右值引用是不合法的,那么即使我们没有将右值 T 传递给构造函数,这种保护也会导致编译时错误。

【讨论】:

  • 我想你的意思是void()void()() 是对 GCC/binutils 的错误拆解,但 was fixed some time ago
  • @Johannes:谢谢!这是有帮助的!
  • 这令人毛骨悚然,我无法理解。关于编译时错误的最后一句话——在这种情况下,SFINAE 不会导致第二个声明被忽略吗?
  • @Kos:这是一个很好的问题,但恐怕我没有一个很好的答案。 SFINAE 规则在标准化过程的后期被推广,并且独立于这个问题。而且我不知道他们是否会捕获对函数的右值引用(如果这种类型无效),并且 SFINAE 会在其上出现或出错,而且我没有办法测试会发生什么.您提出的建议听起来像是该语言可以选择但没有选择的另一种有效设计路径。
  • @Koushik:其他情况需要删除的重载,而不是这个。例如,如果T 实例化为某个结构X,则删除的重载可防止客户端意外将右值X 传递给reference_wrapper。在传递一个函数的情况下,两个重载都被实例化,然后重载解析将选择未删除的一个,因为函数是左值,而不是因为第二个被删除。但重要的是编译器在进行重载解析之前不要声明错误。
【解决方案2】:

在旧的 c++ 标准中,以下是被禁止的:

int foo();
void bar(int& value);

int main()
{
    bar(foo());
}

因为 foo() 的返回类型是一个右值,并且通过引用传递给 bar()。

尽管自(我认为)2005 年以来在 Visual c++ 中启用了 Microsoft 扩展,但这是允许的。

没有 c++0x(或 msvc)的可能解决方法是声明

void bar(const int& value); 

或使用临时变量,存储 foo() 的返回值并将变量(作为引用)传递给 bar():

int main()
{
    int temp = foo();
    bar(temp);
}

【讨论】:

  • 也许我误解了这个问题,但我认为 OP 是在谈论对函数类型(即 lambdas 等)的右值引用。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
相关资源
最近更新 更多