簡體   English   中英

用const進行函數重載的行為

[英]Behavior of function overloading with const

我正在研究g ++,在這里我試圖通過向參數添加const來重載函數。 它工作正常,當它運行時,它調用沒有const

  1. 這種行為是在C ++標准中指定的嗎?
  2. 是什么原因它調用沒有const

     void print(const std::string& str){std::cout << "const" << str << std::endl;} void print(std::string& str){std::cout << str << std::endl;} int main() { std::string temp = "hello"; print(temp); return 0; } 

引用綁定是一個標識類別§13.3.3.1.4 )但由於后者更符合cv,對於§13.3.3.2,非const是首選(來自標准的示例代碼):

int f(const int &);
int f(int &);

int i;
int j = f(i); // calls f(int &)

這是標准行為。 任何其他行為都會導致瘋狂行為。 特別是,非const函數根本不可調用。

const是方法簽名的一部分。 覆蓋僅適用於具有相同簽名的方法。 當您使用基類的const方法調用子類的const方法時,這種行為是為了避免相反的情況。

原因是[over.ics.rank] / 3中的這一部分明確涵蓋了這個案例:

標准轉換序列S1是比標准轉換序列S2更好的轉換序列
[...]
- S1S2是引用綁定(8.5.3),引用引用的類型除了頂級cv限定符之外是相同的類型, S2引用的引用引用的類型更符合cv比S1引用的引用所引用的類型。

S1對應於第二次過載而S2對應於第一次過載。

是什么原因它調用沒有const

你總是試圖選擇最專業的東西。 就像在函數模板的部分排序中那樣,在重載解析中就是這種情況。 第二個重載比第一個重載更專業,因為第一個可以使用參數調用,第二個不能被調用 - 這是此規則背后的基本推理。

重載通過匹配參數的類型(包括限定符)來工作。 在你的情況下, temp類型是std::string而不是const std::string 你只用一個文字常量初始化它,它本身不是常數。

考慮以下:

std::string temp( "hello" ) ;
print(temp);                                    // hello   
print( std::string("hello") ) ;                 // consthello
print( "hello" ) ;                              // consthello
print( static_cast<const std::string>(temp) ) ; // consthello

const std::string temp2( "hello" ) ;
print(temp2);                                    // consthello   

如果要刪除非const版本,則所有三個都將調用剩余的const重載。 在此示例中,實際上只有const版本是必需的(並且是首選的),因為兩個版本都不修改字符串對象。

另一方面,如果你刪除了非const版本,除了上面的第一個例子之外,沒有任何函數匹配,並且構建將失敗。 也就是說非const對象可以安全地作為const參數傳遞,但是const對象不能作為非const參數傳遞,因為該函數不“承諾”不修改對象。 您可以通過const_cast將const強制轉換為非const參數,如下所示:

const std::string temp2("hello") ;
print( const_cast<std::string&>(temp2) ) ;    // hello

但是如果print()在這種情況下試圖修改對象,結果是不確定的 ,那么請考慮這種做法不安全。

使參數const表示意圖,允許編譯器在代碼嘗試修改對象或通過非const參數將其傳遞給其他函數時發出診斷。 它還可能為編譯器提供優化可能性。

因為調用函數采用std::string const&需要兩個隱式轉換:一個到std::string const ,一個到std::string const& ; 而調用函數采用std::string&只需要一次隱式轉換(到std::string& ),因此首選。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM