繁体   English   中英

转发引用,引用限定符和模板成员函数

[英]Forwarding references, ref qualifiers and template member functions

采取以下成员函数:

struct T {
    template <typename X> void f(X&& x) { /* ... */ }
};

在这种情况下, x是转发参考,因为&&用作模板内部的功能参数。 这是预期的。

现在使用此功能:

struct T {
    template <typename X> void f(X&& x) && { /* ... */ }
};

我希望this将以类似的方式处理。 作为转发参考。 因此,我希望以下程序能够编译并运行良好:

#include <iostream>

struct T {
    template <typename X>
    bool operator<(X&& rhs) && {
        std::cout << "&&" << std::endl;
        return true;
    }
};

int main() {
    T t;
    std::cout << (t < T()) << std::endl;
    return 0;
}

但是使用GCC 4.8.4和6.0.1却没有。 相反,我得到以下信息:

rvalue.cpp: In function ‘int main()’:
rvalue.cpp:13:25: error: passing ‘T’ as ‘this’ argument of ‘bool T::operator<(X&&) && [with X = T]’ discards qualifiers [-fpermissive]
 std::cout << (t < T()) << std::endl;

看来this不是转发参考。 这是正确还是错误? 应该this作为转发参考吗? 标准的哪一部分规定了这一点?

这里的两个&& s的区别在于:

struct T {
    template <typename X> void f(X&& x) && { /* ... */ }
};

您是正确的,因为x是转发参考。 但是右边的&&是对象实例的限定条件。 在这种情况下,仅当对象实例为右值时才可以调用f() (可能会增加混淆的是,第一个&&x作为转发引用,而第二个&&将隐式对象参数作为右值引用)。 那是:

T().f(4); // ok

T t;
t.f(4); // error

这与const限定的工作方式相同:

struct X { void f(); };
const X cx;
cx.f(); // error

函数结尾处的参考限定符指出,仅当LHS是临时的时,才应调用operator< 请记住,可以像调用其他任何成员函数一样调用运算符,因此您所拥有的是

t.operator<(T())

t不是临时的。

如果我们将您的示例更改为

std::cout << (T() < t) << std::endl;

这样就可以正常工作了,因为您正在调用operator<的对象是一个临时对象。

成员operator<() &&只能在rvalue上调用,因此以下内容:

t < T()

不起作用,因为t不是rvalue ,而是lvalue

以下应该工作:

std::move(t) < T()

这也是:

T{} < T{}

请注意,我使用{}是因为我对它们更满意,并且它们的工作也并不令人惊讶。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM