簡體   English   中英

為什么不縮小會影響重載分辨率?

[英]Why doesn't narrowing affect overload resolution?

考慮以下:

struct A {
    A(float ) { }
    A(int ) { }
};

int main() {
    A{1.1}; // error: ambiguous
}

這無法編譯,但有關A::A的模糊重載的錯誤。 兩位候選人都被認為是可行的,因為要求很簡單

其次,為了使F成為一個可行的函數,每個參數都應存在一個隱式轉換序列(13.3.3.1),它將該參數轉換為F的相應參數。

雖然存在從doubleint的隱式轉換序列,但A(int )重載實際上不可行(在規范的,非C ++標准意義上) - 這將涉及縮小轉換並因此形成錯誤。

為什么在確定可行的候選人的過程中不考慮縮小轉換? 盡管只有一個候選人可行,但是有沒有其他情況下過載被認為是模棱兩可的?

問題在於可以不基於類型檢測縮小轉換的事實。

在C ++中,有很復雜的方法可以在編譯時生成值。

阻止縮小轉換是一件好事。 使C ++的重載分辨率比現在更復雜是一件壞事。

在確定過載分辨率時忽略縮小轉換規則(這使得過載分辨率完全與類型有關),然后在所選過載導致轉換變窄時出錯,使過載分辨率變得更加復雜,並增加了檢測和防止的方法縮小轉換率。

只有一個候選者可行的兩個例子是在實例化期間“遲到”失敗的模板函數,以及復制列表初始化(考慮explicit構造函數,但如果選擇它們,則會出現錯誤)。 類似地,具有該影響的重載分辨率將使重載分辨率比現在更復雜。

現在,有人可能會問,為什么不將純粹的轉換縮小到類型系統?

縮小轉換純粹是基於類型的轉換是不可行的。 這些更改可能會破壞編譯器可能證明有效的大量“遺留”代碼。 當大多數錯誤是實際錯誤而不是新的編譯器版本是一個混蛋時,掃描代碼庫所需的工作更有價值。

unsigned char buff[]={0xff, 0x00, 0x1f};

這將在基於類型的縮小轉換下失敗,因為0xff的類型為int ,並且此類代碼非常常見。

如果這樣的代碼需要毫無意義地將int文字修改為unsigned char literals,那么我們設置一個標志來告訴編譯器關閉愚蠢的錯誤,那么掃描就會結束。

  • 縮小是編譯器只知道內置類型的東西。 用戶定義的隱式轉換不能標記為縮小。

  • 首先,不應允許縮小轉換。 (不幸的是,這是C兼容性所必需的。在{}初始化禁止縮小內置類型的情況下,這已得到一定程度的糾正。)

鑒於這些,過載規則無需提及這種特殊情況是有道理的。 這可能是偶然的便利,但並不是那么有價值。 IMO通常會更好地減少重載決策所涉及的因素,並拒絕更多不明確的事情,迫使程序員明確地解決這些問題。


另外,當double不是常量表達式或double太大時,double to float是縮小轉換。

#include <iostream>
#include <iomanip>

int main() {
    double d{1.1};
    float f{d};
    std::cout << std::setprecision(100) << d << " " << f << '\n';
}

這通常會產生錯誤:

main.cpp:7:13: error: non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list [-Wc++11-narrowing]
    float f{d};
            ^

暫無
暫無

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

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