【发布时间】:2016-02-14 08:43:40
【问题描述】:
显然,不允许在 ref-qualifiers 上重载 - 如果您删除 & 或 &&(只是标记,而不是它们的函数),此代码将无法编译: p>
#include <iostream>
struct S {
void f() & { std::cout << "Lvalue" << std::endl; }
void f() && { std::cout << "Rvalue" << std::endl; }
};
int main()
{
S s;
s.f(); // prints "Lvalue"
S().f(); // prints "Rvalue"
}
换句话说,如果您有两个具有相同名称和类型的函数,则必须定义两者中的任何一个。我认为这是故意的,但原因是什么?为什么不允许,比如说,如果定义了右值,则调用 && 版本,并在以下变体中的所有其他内容上调用“主要”f()(反之亦然 - 尽管这会令人困惑):
struct S {
void f() { std::cout << "Lvalue" << std::endl; }
void f() && { std::cout << "Rvalue" << std::endl; }
};
换句话说,就主模板而言,让它们的行为类似于模板特化。
【问题讨论】:
-
根据其他重载更改
void f() {...}的含义听起来令人困惑。 -
在实践中从未见过
&/&&限定符。 -
@Lingxi,一种用途是将陷阱变成编译器错误。例如,人们可能会错误地使用
const char* str = getStr().c_str();。您可以使用它来将其转换为编译器错误。不幸的是,目前还没有使它万无一失的方法(即,那里有一个错误,但仍然可以在foo(getStr().c_str());中工作)。我知道它正在研究标准提案。另请参阅this question 了解用途。 -
您不必同时定义两者。只有一个很好。例如。
void f() &&没有f的任何其他定义 -
由于 [over.match.funcs] 13.3.1\5.3,没有 ref-qualifier 的成员函数就像 lvalue 上的双管霰弹枪 s 和 rvalue s 参数。因此,当您声明一个成员函数 with 任何双胞胎 ref-qulifier 时,必须删除该霰弹枪,因为引入了歧义。
标签: c++ c++11 overloading language-lawyer rvalue