2017-06-15 47 views
-2

我現在開始使用自動關鍵字在C++ 11的一件事,我發現它沒有那麼聰明在下面的代碼所示:如何使c + + 11自動更智能?

unsigned int a = 7; 
unsigned int b = 23; 
auto c = a - b; 
std::cout << c << std::endl; 

正如你所看到的,c變量的類型爲unsigned int。但是我的意圖是兩個unsigned int的區別應該是int。所以我期望變量c等於-16。我怎麼能更明智地使用汽車,以便它可以推斷變量的類型爲int?謝謝。

+8

「正如你所看到的,我預計'c'變量的類型應該是'int'」你爲什麼這麼期待? –

+4

'7u - 23u'是一個有效的無符號計算。你爲什麼期望它改變? – CinCout

+1

'auto'非常聰明。整體促銷規則在此不適用(即不需要促銷)。 – StoryTeller

回答

6

ab都有一個類型unsigned int。因此,表達式a - b的類型推導爲unsigned intc具有類型unsigned int。所以汽車這裏工作,因爲它應該做的。

如果你想從unsigned int類型INT您可以使用的static_cast改變類型:

auto c = static_cast<int>(a - b); 

或明確指定類型c

int c = a - b; 
+0

'int c = a - b;'太安全又簡單!我們必須儘可能多地使用C++ 1x功能才能構成! – Lundin

+0

@Lundin像'decltype(auto)c = [](auto a,auto b){return a - b; }(a,b);'? –

+0

是的!你贏了Bjarne Stroustrup的約會。 – Lundin

1

你誤解什麼unsigned int類型是。

unsigned int對於某些k(通常爲32)整數是mod-2^k。減去兩個這樣的mod- 2^k整數是明確定義的,並且不是有符號整數。

如果你想有一個類型的車型有界整數集從-2^k2^k-1(其中k通常等於31),使用int,而不是unsigned int。如果你希望他們是積極的,只要讓他們積極。

儘管它的名字,unsigned int不是int沒有跡象,因此是積極的。相反,它是一種非常具體的整數類型,它恰好沒有符號的概念。

如果你不需要國防部 - 2^k數學一些未知的實現定義k,而不是絕望的幅度的每一個位被打包成一個值,不要使用unsigned int

你似乎什麼要的是像

positive<int> a = 7; 
positive<int> b = 23; 
auto c = a-b; // c is of type `int`, because the difference of two positive values may be negative 

少數語法的變化和很多,可能是可能的工作,但它不是什麼unsigned手段。

1

所以只是因爲不知道基本表達式是如何工作的,C++ 11 auto關鍵字是愚蠢的?這對你有什麼意義?

在表達式auto c = a - b;中,auto c =與在子表達式a - b中使用的類型沒有任何關係。

自從第一個C語言草案表達式使用的類型由該表達式的操作數決定。從預標準K & R C到C++ 17的所有內容都是如此。

現在,如果您想要負數,您需要做的事情不是太奇怪,使用負類型。在調用-運算符之前,將操作數更改爲(有符號)int或將它們轉換爲該類型。

將結果聲明爲帶符號的類型而不改變-的操作數的類型不是一個好主意,因爲那時您強制從無符號到有符號的轉換,這不一定是明確定義的行爲。


現在,如果操作數有不同的類型,或者是小的整數類型的,他們將獲得隱含按照通常的算術轉換推廣。這不適用於這種特定情況,因爲兩個操作數的類型都是相同的,而不是小整數類型。

但是... 這個是爲什麼auto關鍵字是愚蠢和危險的。考慮:

unsigned short a = 7; 
unsigned short b = 23; 
auto c = a - b; 

由於兩個操作數都是無符號的,程序員打算使用無符號算術。但是在這裏,兩個操作數都被隱含地提升爲int,並且意外地改變了簽名。關鍵字auto假設沒有任何事情發生,而unsigned int c = a - b;會增加編譯器診斷消息的機會,或者至少增加來自外部靜態分析工具的警告的機會。而且它也會意外地平滑出本來可能是簽名改變錯誤的東西。

另外,由於auto我們最終會得到聲明變量的錯誤,無意的類型。