簡體   English   中英

重載顯式構造函數的不直觀行為

[英]Unintuitive behavior of overloaded explicit constructors

以下代碼使用(本機 64 位)g++-10 在 64 位 Linux 系統上編譯無警告:

#include <cstdint>

class A {
  public:
    explicit A(unsigned long long int x) { };
    explicit A(uint64_t x) { };
};

int main() {}

但是,在 32 位系統上(相同的 Linux 發行版,相同的版本,但它是 32 位機器),我收到此錯誤:

t.cc:6:14: error: ‘A::A(uint64_t)’ cannot be overloaded with ‘A::A(long long unsigned int)’
    6 |     explicit A(uint64_t x) { };
      |              ^
t.cc:5:14: note: previous declaration ‘A::A(long long unsigned int)’
    5 |     explicit A(unsigned long long int x) { };

我通過實驗測試了位大小(printf-ing sizeof(long long unsigned int) ),是的,它們在 32 位和 64 位系統上都是 8 字節長。

為什么它不能在 32 位系統上編譯?

擴大:

我為此尋找了一點,我在 glibc 頭文件/usr/include/x86_64-linux-gnu/bits/types.h (或/usr/include/i386-linux/bits/types.h )中發現他們的定義因__extension__宏或屬性而異:

#if __WORDSIZE == 64
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
#else
__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;
#endif

我認為這個__extension__很重要。 如果__WORDSIZE == 64 ,因此我們處於 64 位環境中,那么這些類型是兼容的。 如果不是,那么類型定義會因__extension__不同。 這個屬性(宏)來自哪里? 如何制作公平的平台無關代碼?

uint64_t不是基本類型。 它是一個可選的“類型”,是 64 位寬的無符號 integer 類型的別名。 在您的 32 位系統上,這意味着他們很可能將其定義為

using uint64_t = unsigned long long int; 

所以它們是相同的類型,你不能有兩個具有相同簽名的重載

在您的 64 位機器上,他們很可能使用unsigned long int代替,因為這是 64 位 linux 發行版上的 64 位。 這就是為什么它適用於 64 位而不是 32 位的原因。

暫無
暫無

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

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