2013-03-04 211 views
18

common_type<long, unsigned long>::typeunsigned long因爲涉及以後整體推廣的標準說,操作數...爲什麼不是common_type <long,unsigned long> :: type = long long?

[...]如果具有無符號整數類型操作數的秩大於或等於 的類型的秩另一個操作數,與 符號整型操作數應轉換爲操作數的類型與 無符號整型

不叫整體推進體制越野車,但它好像如果有一個更大有符號整數類型wh它可以表示它應該使用的有符號和無符號操作數的範圍。

我知道一些平臺可能有很長的== long long,在這種情況下上述規則可以生效。但是如果有有更大的有符號整型可用,不應該使用它嗎?

+4

我不相信有任何保證'long long'將包含'unsigned long'的整個範圍。如果它與其他規格說明一樣,唯一的要求是它至少與「long」一樣多。無論平臺如何,類型提升都應該是一致的,所以對重載解析有一定的可預測性。 – jpm 2013-03-04 21:36:20

+2

'std :: common_type'匹配確定三元運算符返回類型的規則。從這個角度來看,三元運算符返回比兩個分支都大的類型顯然是錯誤的。 – 2013-03-04 21:37:53

+0

@KevinBallard我其實並不覺得這顯然是錯的。當分支返回不同的簽名時,返回比其中任何一個分支更大的類型似乎是唯一可以保證無缺陷的事情。 – David 2013-03-04 21:52:36

回答

6

首先,std :: common_type(當然boost :: type_traits :: common_type)使用三元運算符來檢索類型結果。在這種情況下,相關的報價來自CppReference,6B)

E2和E3已經算術或枚舉型:常見的算術轉換應用,使他們的常見類型,該類型是結果。

有了這個信息,我們可以找到一個通常的算術轉換規則在c++ standard,5P10,第88頁。

- 否則,如果具有無符號整數類型操作數的排名更高大於或等於另一個操作數的類型的等級,則帶符號整數類型的操作數應轉換爲無符號整數類型的操作數的類型。

所以基本上你的問題的答案是:......因爲標準是這樣說的。

但是,你不是唯一一個發現這種行爲出乎意料的人。這裏有一個快速運行的例子嘗試:

#include <iostream> 
#include <typeinfo> 
#include <type_traits> 

int main(int argc, const char* argv[]) 
{ 

    std::cout << typeid(std::common_type<char, unsigned char>::type).name() << std::endl; 
    // I would expect "short", and the result is "int", ok so far. 

    std::cout << typeid(std::common_type<short, unsigned short>::type).name() << std::endl; 
    // I would expect "int", and the result is "int", yay. 

    std::cout << typeid(std::common_type<int, unsigned int>::type).name() << std::endl; 
    // I would expect "long", but the result is "unsigned int" 

    std::cout << typeid(std::common_type<long, unsigned long>::type).name() << std::endl; 
    // I would expect "long long", but the result is "unsigned long" 


    // So this usual arithmetic conversion can lead to unexpected behavior: 
    auto var_auto = true ? var_i : var_ui; 
    std::cout << typeid(var_auto).name() << std::endl; // unsigned int 
    std::cout << var_auto << std::endl;     // 4294967173 

    return 0; 
} 

但是,目前的行爲是一個問題是knownproposal的存在是爲了去除一些驚喜。

-Hannes

+0

那麼你的問題是什麼?我回答「爲什麼不是common_type :: type = long long?」您的示例不會添加比我的示例更多的信息,請糾正我,如果我錯了。但當然,1 <* Maxulong * -1 ... – 2013-03-13 19:42:00

+0

這個問題很清楚,標準確實說明了它是這樣的,我不需要一個答案來重申它是這樣的,因爲標準是這樣說的* 。但就像我說的,我很高興你的鏈接在底部,它們是相關的並且是部分答案(因爲這是一個已知的'問題',但並沒有說明爲什麼它是以這種方式開始的) – David 2013-03-13 21:10:49

相關問題