C ++ 11の「typedef」と「using」の違いは何ですか?

949
Klaim 2012-05-25 16:39.

C ++ 11ではusing、次のような型エイリアスの記述に使用できるようになりましたtypedef

typedef int MyInt;

私が理解していることから、次のようになります。

using MyInt = int;

そして、その新しい構文は、「template typedef」を表現する方法を持つ努力から生まれました。

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

しかし、最初の2つの非テンプレートの例では、標準に他の微妙な違いはありますか?たとえば、typedefsは「弱い」方法でエイリアシングを行います。つまり、新しいタイプは作成されず、新しい名前のみが作成されます(変換はこれらの名前間で暗黙的に行われます)。

それは同じusingですか、それとも新しいタイプを生成しますか?違いはありますか?

7 answers

29
dfrib 2020-06-05 03:50.

以下のすべての標準参照は、N4659:2017年3月のコナ後の作業ドラフト/ C ++ 17DISを参照しています。


Typedef宣言は使用できますが、エイリアス宣言は初期化ステートメントとして使用できません。

しかし、最初の2つの非テンプレートの例では、標準に他の微妙な違いはありますか?

  • セマンティクスの違い:なし。
  • 許可されるコンテキストの違い:いくつか(1)

(1)元の投稿ですでに言及されているエイリアステンプレートの例に加えて。

同じセマンティクス

[dcl.typedef] / 2 [抽出、強調鉱山]によって管理されます

【dcl.typedef] / 2 A型定義名によっても導入することができるエイリアス宣言識別子以下のusingキーワードがなりのtypedef名とオプションの属性指定子-seqの識別子とappertainsのtypedef名このようなtypedef-nameは、typedef指定子によって導入された場合と同じセマンティクスを持ちます。[...]

alias-declarationによって導入されたtypedef-name宣言によって導入された場合と同じセマンティクスを持ちtypedefます。

許可されたコンテキストの微妙な違い

ただし、これは、2つのバリエーションがどのコンテキストで使用されるかについて同じ制限があることを意味するものではありませ。実際、コーナーケースではありますが、typedef宣言initステートメントであるため、初期化ステートメントを許可するコンテキストで使用できます。

// C++11 (C++03) (init. statement in for loop iteration statements).
for(typedef int Foo; Foo{} != 0;) {}

// C++17 (if and switch initialization statements).
if (typedef int Foo; true) { (void)Foo{}; }
//  ^^^^^^^^^^^^^^^ init-statement

switch(typedef int Foo; 0) { case 0: (void)Foo{}; }
//     ^^^^^^^^^^^^^^^ init-statement

// C++20 (range-based for loop initialization statements).
std::vector<int> v{1, 2, 3};
for(typedef int Foo; Foo f : v) { (void)f; }
//  ^^^^^^^^^^^^^^^ init-statement

for(typedef struct { int x; int y;} P;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ init-statement
    auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) { (void)x; (void)y; }

一方、エイリアス宣言initステートメントではないため、初期化ステートメントを許可するコンテキストでは使用できません。

// C++ 11.
for(using Foo = int; Foo{} != 0;) {}
//  ^^^^^^^^^^^^^^^ error: expected expression

// C++17 (initialization expressions in switch and if statements).
if (using Foo = int; true) { (void)Foo{}; }
//  ^^^^^^^^^^^^^^^ error: expected expression

switch(using Foo = int; 0) { case 0: (void)Foo{}; }
//     ^^^^^^^^^^^^^^^ error: expected expression

// C++20 (range-based for loop initialization statements).
std::vector<int> v{1, 2, 3};
for(using Foo = int; Foo f : v) { (void)f; }
//  ^^^^^^^^^^^^^^^ error: expected expression
593
Jesse Good 2012-05-25 17:16.

それらは、標準(強調鉱山)(7.1.3.2)から同等です:

typedef-nameは、alias-declarationによって導入することもできます。usingキーワードに続く識別子はtypedef-nameになり、識別子に続くオプションのattribute-specifier-seqはそのtypedef-nameに関連します。typedef指定子によって導入された場合と同じセマンティクスを持ちます。特に、新しいタイプを定義せず、type-idに表示されません。

248
Zhongming Qu 2015-10-06 12:58.

それらは、次の点を除いて、ほとんど同じです。

エイリアス宣言はテンプレートと互換性がありますが、Cスタイルのtypedefは互換性がありません。

201
4xy 2014-04-22 01:39.

使用して、テンプレート内で使用する場合の構文は利点があります。型の抽象化が必要であるが、将来指定できるようにテンプレートパラメータを保持する必要がある場合。あなたはこのような何かを書くべきです。

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; }

ただし構文を使用すると、このユースケースが単純化されます。

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

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
23
Validus Oculus 2018-03-31 22:20.

それらは本質的に同じですが、非常に便利なものをusing提供しますalias templates。私が見つけた良い例の1つは次のとおりです。

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

だから、std::add_const_t<T>代わりに使うことができますtypename std::add_const<T>::type

13
RoboticForest 2019-06-12 16:59.

元のポスターには素晴らしい答えがあることは知っていますが、私のようにこのスレッドに出くわした人にとっては、ここでの議論に何か価値があると思う重要なメモがあります。特に、typedefキーワードが将来的に非推奨としてマークされるか、冗長/古いために削除されます:

キーワードtypedef ...を(再)使用してテンプレートエイリアスを導入することが提案されています。

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

この表記には、タイプエイリアスを導入するためにすでに知られているキーワードを使用するという利点があります。ただし、エイリアスがタイプではなくテンプレートを指定するコンテキストで、タイプ名のエイリアスを導入することが知られているキーワードを使用することの混乱など、いくつかの欠点も表示されます。Vecは型のエイリアスではないため、typedef-nameと見なすべきではありません。名前Vecはファミリの名前です。std::vector<•, MyAllocator<•> >ここで、箇条書きはtype-nameのプレースホルダーです。したがって、「typedef」構文は提案しません。一方、文は

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

次のように読み取る/解釈できます。これからは、Vec<T>の同義語として使用しますstd::vector<T, MyAllocator<T> >。その読み方からすると、エイリアシングの新しい構文はかなり論理的であるように思われます。

私にとって、これは、typedefコードをより読みやすく理解しやすくすることができるため、C ++でのキーワードの継続的なサポートを意味します

更新using(受け入れ答えで指摘したように)キーワードを使用すると、非テンプレートで作業しているとき、テンプレートのために特別だった、とusingしてtypedef選択は読みやすさと意思のコミュニケーションを理由にプログラマに完全にアップしているので、機械的に同一であり、 。

3
marski 2019-12-03 12:23.

両方のキーワードは同等ですが、いくつかの注意点があります。1つは、で関数ポインタを宣言する方が、で宣言するusing T = int (*)(int, int);よりも明確であるということtypedef int (*T)(int, int);です。2つ目は、テンプレートエイリアス形式はtypedef。では使用できないことです。3つ目は、CAPItypedefを公​​開するにはパブリックヘッダーが必要になるということです。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

ゲッティ経由の画像。スコット・プルイットは環境保護庁の長であり、二酸化炭素とメタンガスとの愛情のこもった関係を持っていますが、彼は地球温暖化を信じることに冷たい肩を与えています。

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

一連の点滅する省略記号であろうと、「誰かが入力している」という明示的な通知であろうと、入力インジケーターと呼ばれるメッセージング機能は、多くの人にとって便利なツールであり、不安の原因でもあります。しかし、それがどのように機能するかについてもっと知ることは、少なくとも私たちにストレスを引き起こす推測ゲームを制限することができます。

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーと彼の妻のアネット・ロークは結婚間近であり、離婚手続きが激化していると伝えられています。ある情報筋は、ラウアーが「和解で約5,000万ドルをフォークする予定」であり、「マットは激怒している」と語った。彼は本質的に彼の純資産の半分をアネットに手渡している。

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

2018年6月15日金曜日、カリフォルニア州ビスタでの罪状認否の際、元NFLフットボール選手のケレンウィンズロージュニア(中央)が弁護士のブライアンワトキンス(左)とハーベイスタインバーグの後ろに立っています。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language