C ++ 11中的'typedef'和'using'有什麼區別?

本文翻譯自:What is the difference between 'typedef' and 'using' in C++11?

I know that in C++11 we can now use using to write type alias, like typedef s: 我知道在C ++ 11中,我們現在可以使用using來編寫類型別名,例如typedef

typedef int MyInt;

Is, from what I understand, equivalent to: 據我瞭解,相當於:

using MyInt = int;

And that new syntax emerged from the effort to have a way to express " template typedef ": 並且,這種新語法是通過努力表達“ template typedef ”的方式而出現的:

template< class T > using MyType = AnotherType< T, MyAllocatorType >;

But, with the first two non-template examples, are there any other subtle differences in the standard? 但是,對於前兩個非模板示例,標準中是否還有其他細微差別? For example, typedef s do aliasing in a "weak" way. 例如, typedef會以“弱”方式進行別名。 That is it does not create a new type but only a new name (conversions are implicit between those names). 也就是說,它不會創建新的類型,而只會創建一個新名稱(這些名稱之間的轉換是隱式的)。

Is it the same with using or does it generate a new type? 是否與using相同或會生成新類型? Are there any differences? 有什麼區別嗎?


#1樓

參考:https://stackoom.com/question/j5zm/C-中的-typedef-和-using-有什麼區別


#2樓

They are equivalent, from the standard (emphasis mine) (7.1.3.2): 它們與標準(強調我的)(7.1.3.2)是等效的:

A typedef-name can also be introduced by an alias-declaration. typedef名稱也可以通過別名聲明來引入。 The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. using關鍵字後面的標識符變爲typedef名稱,而標識符後面的可選attribute-specifier-seq屬於該typedef名稱。 It has the same semantics as if it were introduced by the typedef specifier. 它具有與typedef說明符引入的語義相同的語義。 In particular, it does not define a new type and it shall not appear in the type-id. 特別是,它沒有定義新的類型,也不應出現在type-id中。


#3樓

The using syntax has an advantage when used within templates. 在模板中使用時, using語法具有優勢。 If you need the type abstraction, but also need to keep template parameter to be possible to be specified in future. 如果需要類型抽象,還需要保留模板參數,以便將來可以指定。 You should write something like this. 你應該這樣寫。

template <typename T> struct whatever {};

template <typename T> struct rebind
{
  typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};

rebind<int>::type variable;

template <typename U> struct bar { typename rebind<U>::type _var_member; }

But using syntax simplifies this use case. 但是使用語法可以簡化此用例。

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }

#4樓

They are largely the same, except that: 它們基本相同,除了:

The alias declaration is compatible with templates, whereas the C style typedef is not. 別名聲明與模板兼容,而C風格的typedef不兼容。


#5樓

They are essentially the same but using provides alias templates which is quite useful. 它們本質上是相同的,但是using提供了非常有用的alias templates One good example I could find is as follows: 我可以找到一個很好的例子,如下所示:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

So, we can use std::add_const_t<T> instead of typename std::add_const<T>::type 因此,我們可以使用std::add_const_t<T>代替typename std::add_const<T>::type


#6樓

I know the original poster has a great answer, but for anyone stumbling on this thread like I have there's an important note from the proposal that I think adds something of value to the discussion here, particularly to concerns in the comments about if the typedef keyword is going to be marked as deprecated in the future, or removed for being redundant/old: 我知道原始發帖人的回答很好,但是對於像我這樣絆腳石的任何人,提案中都有一條重要說明,我認爲這對此處的討論特別是對typedef關鍵字是否在註釋中的關注增加了一些價值。將來將被標記爲已棄用,或由於冗餘/舊而被刪除:

It has been suggested to (re)use the keyword typedef ... to introduce template aliases: 已建議(重新)使用關鍵字typedef ...引入模板別名:

 template<class T> typedef std::vector<T, MyAllocator<T> > Vec; 

That notation has the advantage of using a keyword already known to introduce a type alias. 該符號的優點是使用已知的關鍵字來引入類型別名。 However, it also displays several disavantages [sic] among which the confusion of using a keyword known to introduce an alias for a type-name in a context where the alias does not designate a type, but a template; 但是,它也顯示了一些不足之處,其中在別名不是指定類型而是模板的情況下,使用已知爲類型名稱引入別名的關鍵字會造成混淆。 Vec is not an alias for a type, and should not be taken for a typedef-name. Vec 不是類型的別名,並且不應將其用作typedef名稱。 The name Vec is a name for the family std::vector<•, MyAllocator<•> > – where the bullet is a placeholder for a type-name.Consequently we do not propose the “typedef” syntax.On the other hand the sentence Vec名稱是std::vector<•, MyAllocator<•> >家族的名稱–項目符號是類型名稱的佔位符。因此,我們不建議使用“ typedef”語法。句子

 template<class T> using Vec = std::vector<T, MyAllocator<T> >; 

can be read/interpreted as: from now on, I'll be using Vec<T> as a synonym for std::vector<T, MyAllocator<T> > . 可以理解爲: 從現在開始,我將使用Vec<T>作爲std::vector<T, MyAllocator<T> >的同義詞 With that reading, the new syntax for aliasing seems reasonably logical. 通過閱讀,別名的新語法似乎是合理的。

To me, this implies continued support for the typedef keyword in C++ because it can still make code more readable and understandable . 對我來說,這意味着將繼續支持C ++中的typedef關鍵字,因爲它仍然可以使代碼更具可讀性和可理解性

Updating the using keyword was specifically for templates, and (as was pointed out in the accepted answer) when you are working with non-templates using and typedef are mechanically identical, so the choice is totally up to the programmer on the grounds of readability and communication of intent. 更新using關鍵字是專門爲模板,並(在接受的答案指出)當你與非模板工作usingtypedef是機械上相同的,所以在選擇完全取決於可讀性的理由和程序員目的溝通。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章