转发引用、引用限定符和模板成员函数
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 —左值
下面的代码应该可以工作:
std::move(t) < T()
和this too:
T{} < T{}
请注意,我已经使用了{}
,因为我更熟悉它们,它们的工作没有太大的惊喜。
相关文章:
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 无法将右值引用函数与 GCC 匹配
- C ++引用函数参数似乎包含原始对象的副本,而不是充当"real reference"
- 通过引用函数传递指针参数是什么意思?
- 常量引用函数参数的地址何时唯一?
- 我想了解为什么在这个例子中使用引用函数?或者引用在c++函数中的重要性
- C++ 通过引用函数传递数组,但内容保持不变
- 用数组或指针引用函数?
- 引用函数如何"int &foo();"工作?
- 常量引用函数参数:是否可以禁止临时对象?
- 计算在代码中引用函数的次数
- <initializer_list> 引用函数
- 字符串引用(函数)的差异
- 在类中引用函数时的"No Matching Function for Call"
- 无法通过引用函数"calcValues"中"firstNum"和"secondNum"变量来更改值
- 尝试引用已删除的函数(不引用函数)
- 引用函数指针
- 引用函数按值和自动返回
- 为什么我们可以取消引用函数指针
- 通过引用函数传递值的目的是什么