[英]Trouble with const/non-const overload resolution
我有一個看起來像這樣的 class:
class ClassA
{
public:
float Get(int num) const;
protected:
float& Get(int num);
}
在 class 之外,我調用 Get() function。
float foo = classAInstance.Get(i);
我希望這會調用公共版本,但 Visual Studio 會出錯:
error C2248: 'ClassA::Get' : cannot access protected member declared in class 'ClassA'
當注釋掉受保護的重載並刪除對它的所有引用時,代碼會編譯。
當一個可訪問的成員可用時,為什么編譯器會嘗試使用不可訪問的成員? 是否有一種公認的方式來強制編譯器選擇正確的重載? 是否在某處引用了成員函數的解析規則?
確實,重載決議發生在可訪問性檢查之前。 標准的第 13.3 節( [over.match]
)說:
重載解析是一種機制,用於選擇最佳 function 來調用給定的表達式列表,這些表達式將成為調用的 arguments 和一組可以根據調用上下文調用的候選函數。 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候選 function 的屬性。 [注:重載決議選擇的function不保證適合上下文。 其他限制,例如 function 的可訪問性,可以使其在調用上下文中的使用格式不正確。 ——尾注]
通常的解決方法是為公共和受保護的函數賦予不同的名稱。
請注意,這有時很有用,例如:
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()
中的未定義行為。
Blah c("Kablooey!"); // would be undefined behavior
// the constructor overload makes this a compile error
私有構造函數重載防止臨時std::string
被隱式構造和綁定。
重載解決首先完成,然后訪問檢查。
如果你同時有一個 const 和一個非常量重載,這可以通過 object 的 constness 解決,需要 function。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.