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

时间:2016-08-30 15:54:10

标签: c++ templates language-lawyer member-functions forwarding-reference

采取以下成员函数:

if (identities2.contains(identities[indexPath.row])) {
    cell.imageView = UIImage(named: identities[indexPath.row]) 
}
else {
    cell.imageView = UIImage(named: "DefaultGrayImage") //Set default image not in identities2
}

在这种情况下,struct T { template <typename X> void f(X&& x) { /* ... */ } }; 是转发引用,因为x用于模板内的函数参数。这是预期的。

现在采取这个功能:

&&

我希望struct T { template <typename X> void f(X&& x) && { /* ... */ } }; 会以类似的方式对待;作为转发参考。因此,我希望以下程序能够编译并运行得很好:

this

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

#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;
}

似乎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应该被视为转发参考吗?该标准的哪一部分规定了这一点?

3 个答案:

答案 0 :(得分:3)

这里的两个&& s`的处理方式不同:

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

你是正确的x是转发参考。但是右边的&&是对象实例的限定条件。在这种情况下,f()只能在对象实例是右值时调用(可能会引起混淆的是第一个&&x作为转发引用而第二个{{ 1}}将隐式对象参数作为右值引用)。那就是:

&&

这与T().f(4); // ok T t; t.f(4); // error 资格认证的工作方式相同:

const

答案 1 :(得分:2)

函数末尾的引用限定符表明只有在LHS是临时的时才应调用operator<。记住,可以像任何其他成员函数一样调用操作符,所以你拥有的是

t.operator<(T())

t不是暂时的。

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

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

然后它就可以了,因为你调用operator< on的对象是一个临时对象。

答案 2 :(得分:0)

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

t < T()

不起作用,因为t不是 rvalue - 它是 lvalue

以下内容应该有效:

std::move(t) < T()

这也是:

T{} < T{}

请注意,我已经使用了{},因为我对它们感觉更舒服,并且它们的工作没有太多意外。