使用const /非const重载分辨率的问题 [英] Trouble with const/non-const overload resolution

查看:191
本文介绍了使用const /非const重载分辨率的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类看起来像这样:

I have a class that looks something like this:

class ClassA
{
  public:
    float Get(int num) const;
  protected:
    float& Get(int num);
}

在类外面,我调用Get()函数。

Outside of the class, I call the Get() function.

float foo = classAInstance.Get(i);



我希望这可以调用公共版本,而是Visual Studio错误:

I expect this to call the public version, but instead Visual Studio errors out:

error C2248: 'ClassA::Get' : cannot access protected member declared in class 'ClassA'

当注释掉受保护的重载并删除对它的所有引用时,代码将编译。

When commenting out the protected overload and removing all references to it, the code compiles.

为什么编译器尝试在可访问的成员可用时使用不可访问的成员?是否有一种被接受的方式强制编译器选择正确的重载?

Why does the compiler try to use the inaccessible member when an accessible one is available? Is there an accepted way to force the compiler to choose the correct overload? Is there a reference to the resolution rules for member functions somewhere?

推荐答案

这是真的,重载解析发生在辅助功能检查之前。标准的第13.3节( [over.match] )说:

It's true, overload resolution takes place before accessibility checks. Section 13.3 of the standard ([over.match]) says:


分辨率是一种机制,用于选择最佳函数调用给定的表达式列表
作为调用的参数和一组候选函数,可以基于
调用的调用。最佳函数的选择标准是参数的数量,参数
与候选函数的参数类型列表匹配的程度,
对象(非静态成员函数)的匹配程度隐式对象参数,以及候选函数的某些其他属性。 [注意:
通过重载分辨率选择的函数不能保证适用于上下文。其他
限制,例如函数的可访问性,可以使其在调用上下文中的使用不成体。
- end note]

Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the implicit object parameter, and certain other properties of the candidate function. [ Note: The function selected by overload resolution is not guaranteed to be appropriate for the context. Other restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed. — end note ]

通常的解决方法是为公共和受保护的函数提供不同的名称。

The usual fix is to give the public and protected functions different names.

注意,这在有时候很有用,例如:

Note, this is useful sometimes, example:

class Blah
{
    const std::string& name_ref;

    Blah(const char*) = delete;

public:
    Blah(const std::string& name) : name_ref(name) {}

    void do_something_with_name_ref() const;
};

std::string s = "Blam";
Blah b(s); // ok

请注意, name_ref 从中读取,所以它是适当的使它 const 。但是, const 引用可以绑定到临时表,并且将 name_ref 绑定到临时表达式将是一个悬挂引用,导致未定义行为在 do_something_with_name_ref()

Note that name_ref will only be read from, so it's appropriate to make it const. However, const references can bind to temporaries, and binding name_ref to a temporary would be a dangling reference, resulting in undefined behavior in do_something_with_name_ref().

Blah c("Kablooey!"); // would be undefined behavior
                     // the constructor overload makes this a compile error

private构造函数重载防止临时 std :: string 被隐式构造和绑定。

The private constructor overload prevents a temporary std::string from being implicitly constructed and bound.

这篇关于使用const /非const重载分辨率的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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