我看到在宏內使用decltype(x)
其中x
是一個變量名稱,因爲對象的類型在宏內部是未知的。什麼時候應該使用decltype(x)而不是auto來聲明變量的類型?
例如:
decltype(x) y = expr;
我可以很容易地使用auto
代替decltype
。那麼decltype
需要變量類型聲明而不是auto
?
我看到在宏內使用decltype(x)
其中x
是一個變量名稱,因爲對象的類型在宏內部是未知的。什麼時候應該使用decltype(x)而不是auto來聲明變量的類型?
例如:
decltype(x) y = expr;
我可以很容易地使用auto
代替decltype
。那麼decltype
需要變量類型聲明而不是auto
?
應該使用它時所需的y
類型是:
expr
類型不同(或可能不同)。如果它是相同的,那麼auto
會更簡潔。auto &
或expr
類型的其他修改auto
可以表示。和下列之一:
decltype
可以幫助您定義一個特徵。因此,例如更換std::iterator_traits<RandomAccessIterator>::value_type
與decltype(*it)
很可能是一場勝利,雖然auto
不經常處理這樣的情況。主觀判斷進入「什麼是困難」,「什麼是囉嗦」和「什麼是明確的」,但是無論在特定情況下如何做出這些判斷,程序規則都可以是相同的。
但是在''decltype(x)y = expr;''這裏''y''和''expr''不是同一類型的情況下,寫''auto y = x (表達式);''?或者這是否僅僅反映個人偏好,以及是否希望進行明確的轉換? –
@ DiederickC.Niehorster:如果'x'是類型,那麼你只需寫'x y = expr;'(或'x y {expr};'),而不是這兩者中的任何一個。我認爲這個問題假定'x'不是一種類型。如果'x'不是一個類型,那麼'x(expr)'可能不起作用。如果它是一個類型,它是一個「可怕的」C風格的演員,它可能會做'const_cast'或'reinterpret_cast'或者兩者都取決於'x'類型的結束。更好地使用'static_cast'。 –
只要您的變量類型與正在評估的表達式無關。
E.g:
struct Bar
{
Bar(int) {} // implicitly constructable
}
struct Bar2
{
Bar2(int) {} // implicitly constructable
}
struct Foo
{
static Bar var;
}
struct Foo2
{
static Bar2 var;
}
template <typename T>
void dummy()
{
decltype(T::var) myVar = 42;
}
dummy<Foo>(); // myVar is of type Bar1
dummy<Foo2>(); // myVar is of type Bar2
auto myAutoVar = 42; // type is int
當然,這只是一個使用情況下,有更多的在那裏。
當你想y
總是有任何聲明的類型x
是。
但是我仍然會知道'x'的類型,所以我可以用'[typeOfX] y = expr'替換'decltype(x)'。 –
這使得'y'始終具有該特定類型。不一樣。 –
@templateboy你總是知道'foo(a + b/c)'的返回類型嗎? – Flexo
decltype
是顯着更多才多藝,auto
,可以始終用它來代替它。因此,我認爲decltype
只能在完全必要的情況下才能使用,所以如果auto
產生錯誤的結果,應該使用decltype。此外,您還不能使用auto
作爲回報類型和參數,因此您也可以在此處使用decltype
。 C++ 14將顯着增加auto
的潛在用途,我想C++ 17會走得更遠。所以情況下使用decltype
將只有當你需要更改所得到的expr
另一個要考慮的類型是decltype
是不是真的有必要,除非你正在編寫庫代碼,汽車是日常編程如果不錯你想讓你的代碼更加簡潔,但是儘可能使用盡可能多的auto
是有好處的,但在使用類似lambda表達式的類型時,這是非常必要的。
decltype
當你需要返回一些未知類型,這是在編譯期間評估變得得心應手:
template<class A, class B>
void MultiplyAB(A a, B b, decltype(a*b)& output)
{
output = a * b;
}
此外,如果你不喜歡的輸出由參考處理的方式,那麼你就可以還使用後期指定的返回類型(和也使用decltype
):
template<class A, class B>
auto MultiplyAB(A a, B b) -> decltype(a*b)
{
return a * b;
}
所有這一切,更多的,由B. Stroustrup的在C++ FAQ說明。
TBH後者沒有定義變量的類型,它定義了返回類型。 – MSalters
在你的問題的情況下,
當你想與正是由於原始變量相同類型一個新的變量,您應該使用decltype
。
當你想分配一些表達式的值到一個新的變量,你想要或需要的類型推斷應該使用auto
。
decltype(x) y
總是宣稱y
與嚴格的相同類型的x
與聲明的類型。特別是:
x
的類型爲const int
然後y
將有類型const int
。x
具有類型int[100]
那麼y
將具有類型int[100]
。x
具有類型int f(int)
則y
將具有類型int f(int)
。是的,這實際上聲明瞭另一個函數與原始類型相同。x
有類型int&
然後y
將有類型int&
;並且如果x
具有類型int&&
,則y
將具有類型int&&
。auto y = x
將宣佈y
有以下類型,當x
有以下幾種類型:
x
有類型const int
,然後y
將有類型int
。即,auto
剝離頂級cv限定符。x
具有類型int[100]
,則y
將具有類型int*
。也就是,auto
執行數組到指針轉換。 [1]x
具有類型int f(int)
,那麼y
將具有類型int (*)(int)
。也就是說,auto
執行的功能爲一個函數指針轉換。 [2]x
具有類型int&
或int&&
,則y
將具有類型int
。即,auto
刪除引用。[1]此處不能使用decltype
,因爲您無法複製初始化數組。
[2],則不能使用decltype
這裏,因爲你無法初始化函數。
[3]之所以auto
條的引用是,C++沒有引用類型的表達式!一旦初始化,參考的「參考性」就變得不可見。
注意decltype
也做完全不同的事情,當它的參數不是ID表達,我不會進入這裏。
'decltype(X)Y = EXPR;'是不一樣的'自動Y = EXPR;' - 可能有很大可能是某種形式的在前者的隱式轉換,但不是在後者。 – Flexo
'auto'適合普通人和日常使用。 'decltype'用於通常的庫代碼,在正常生活中你應該幾乎看不到它。 –
** <評論刪除> **評論不適合長時間討論問題的主題。如果你想進一步討論這個問題是否在話題上,請訪問[Meta Stack Overflow](http://meta.stackoverflow.com)。 – animuson