c ++:关于转发引用的混乱 [英] c++: confusion about forwarding reference

查看:170
本文介绍了c ++:关于转发引用的混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了(令人难以置信的

I read this (incredibly well written) article about Forwarding Reference in C++11 by Scott Meyers.

现在,关注本文的这一部分:

Now, focus on this part of the article:


template <class... Args>
void emplace_back(Args&&... args); // deduced parameter types ⇒ type deduction;
...                                // && ≡ universal references


因此,与其他情况相比,椭圆不会使&&& 一个右值引用,但它仍然是通用引用。

So, in contrast with other cases, the ellipses doesn't make the && an rvalue reference, but it's still universal references.

当我们有通用引用时,我们可以调用传递rvalue和lvalues的函数(哇,这么酷!)

From what I've understood, when we have universal references, we can call the function passing both rvalue and lvalues (wow, so cool!)

现在,我实现了这个函数:

Now, I've implemented this function:

template <typename ReturnType, typename... Args>
ReturnType callFunction(MemFunc<ReturnType, Args...> memFunc, Args&& ... args) { ...

因此(使用与上例相同的逻辑),&&& 表示转发引用。

So (using the same logic of the previous example), && means forwarding references.

如果我尝试拨打此电话:

But if I try to make this call:

typedef vector<double> vecD;
vecD vec;
mem.callFunction<vecD, vecD>(sortFunc, vec);

编译器将抱怨<​​code>您不能将左值绑定到右值参考

为什么会发生这种情况?

Why this happens?

/ strong>

THE WHOLE CODE:

#include <functional>
#include <vector>

using namespace std;
struct MultiMemoizator {
    template <typename ReturnType, typename... Args>
    ReturnType callFunction(std::function<ReturnType(Args...)> memFunc, Args&&... args) {

    }
};

typedef vector<double> vecD;

vecD sort_vec (vecD const& vec) {
    return vec;
}

int main()
{
    vecD vec;
    std::function<vecD(vecD)> sortFunc(sort_vec);
    MultiMemoizator mem;
    mem.callFunction<vecD, vecD>(sortFunc, vec);
}


推荐答案

转发参考而不是通用参考。

So first off, please use the "forwarding reference" instead of "universal reference". It better represents what it is and what is it's intended use.

首先要注意的不是每个&&& / code>是转发引用。它也可以是一个右值引用。

The first thing to be aware of is that not every && is a forwarding reference. It can also be an rvalue reference.

简单来说, T&&& if:


  • T 是一个简单的如下所示)类型(因此例如向量&& 向量< T>&& 转发参考)。

  • T b $ b
  • T is a simple (simple as shown next) type (so for instance vector<int>&& or vector<T>&& is not a forwarding reference).
  • and T is deduced.

在您的示例中,不会推导出 Args 。这是因为你在调用它时显式指定函数模板参数 Args

In your example Args is not deduced. That is because you explicitly specify the function template argument Args when you call it:

mem.callFunction<vecD, vecD>(sortFunc, vec);
                       ^~~~






更容易理解:


Let's work with something simpler to better understand:

让我们设置场景:

struct X {};

template <class T>
auto foo(T&& p) {}

我们有转发参考:

X x;
foo(x);

foo(X{});

在第一步中,将推导出 T X& 和折叠规则: X& &&&< / code>变为 X& ,因此我们有一个左值引用。

In the first, T will be deduced as X& and by collapsing rules: X& && becomes X&, therefore we have an lvalue reference. As you would expect.

第二, T 将被推导为 X 和折叠规则 X&&& 变成 X&&&

In the second, T will be deduced as X and by collapsing rules X && becomes X&&, therefore we have an rvalue reference.

但是当你这样调用时:

foo<X>(x);

T 你基本上说让 T X 。因此,如果 T X ,则 T&是 X&& ,并且您有以下错误: p ,类型为

T is no longer deduced. You basically say let T be X. So if T is X then T && is X&&, and you have the error: p whose type is now X&& cannot bind to an lvalue.

Holt也添加了


还要注意,由于声明了sortFunc,即使没有指定函数模板参数也不会
工作

Also note that because of the declaration of sortFunc, this would not work even if you did not specify the function template arguments explicitely.

我倾向于同意他的观点,但我需要进一步调查以确定这一点。

I tend to agree with him, but I would need to investigate further to be sure of this.

这篇关于c ++:关于转发引用的混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆