为什么不允许仅在一个引用限定符上进行重载? [英] Why is overloading on just one ref-qualifier not allowed?

查看:71
本文介绍了为什么不允许仅在一个引用限定符上进行重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

显然,不允许在引用限定符上超载 –如果您删除& &&(只是令牌,而不是其功能):

Apparently, overloading on ref-qualifiers is not allowed – this code won't compile if you remove either & or && (just the tokens, not their functions):

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

换句话说,如果您拥有两个具有相同名称和类型的功能,则必须同时定义这两个功能.我认为这是故意的,但是原因是什么?为什么不允许说,例如,定义右值的&& 版本,并在以下变体中的所有其他内容上调用"primary" f()反之亦然-尽管那会造成混乱):

In other words, if you have two functions of the same name and type, you have to define both if you define either. I assume this is deliberate, but what's the reason? Why not allow, say, calling the && version for rvalues if it's defined, and the "primary" f() on everything else in the following variation (and vice-versa – although that would be confusing):

struct S {
    void f()    { std::cout << "Lvalue" << std::endl; }
    void f() && { std::cout << "Rvalue" << std::endl; }
};

换句话说,就主模板而言,让它们的行为类似于模板专业化.

In other words, let them act similar to template specializations with respect to the primary template.

推荐答案

与以下情况没有什么不同:

It's not any different to the following situation:

struct S {};

void g(S s);
void g(S& s);

int main()
{
    S s;
    g(s);     // ambiguous
}

重载解析一直以这种方式起作用;通过引用传递而不是通过值传递(反之亦然).

Overload resolution has always worked this way; passing by reference is not preferred to passing by value (or vice versa).

(ref限定函数的重载解析就像是一个普通函数,带有隐式第一个参数,其参数为 * this ; lvalue-ref限定类似于第一个参数 S& const& 就像 S const& 等)

(Overload resolution for ref-qualified functions works as if it were a normal function with an implicit first parameter whose argument is *this; lvalue-ref qualified is like a first parameter S &, const & is like S const & etc.)

我猜你是说 g(s)应该调用 g(S&)而不是模棱两可.

I guess you are saying that g(s) should call g(S&) instead of being ambiguous.

我不知道确切的理由,但是重载解析非常复杂,因为它没有添加更多特殊情况(尤其是那些可能默默编译为编码器意图之外的情况).

I don't know the exact rationale, but overload resolution is complicated enough as it is without adding more special cases (especially ones that may silently compile to not what the coder intended).

正如您在问题中指出的那样,使用两个版本的 S& S&& 可以轻松避免此问题.

As you note in your question, the problem can be easily avoided by using the two versions S & and S &&.

这篇关于为什么不允许仅在一个引用限定符上进行重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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