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

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

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

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

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

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

2021 年 6 月 8 日にニューヨーク市で開催された covid-19 パンデミックで亡くなった人々の命を偲び、祝うために、ネーミング ザ ロスト メモリアルズが主催するイベントと行進の最中に、グリーンウッド墓地の正門から記念碑がぶら下がっています。週末、ジョー・バイデン大統領は、covid-19 パンデミックの終息を宣言しました。これは、過去 2 年以上にわたり、公の場でそうするための長い列の中で最新のものです。

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

オハイオ州のエミリー・デシャネル みんな早く来て、ボーンズが帰ってきた!まあ、ショーボーンズではなく、彼女を演じた俳優. エミリー・デシャネルに最後に会ってからしばらく経ちました.Emily Deschanel は、長期にわたるプロシージャルな Bones の Temperance “Bones” Brennan としてよく知られています。

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

どうやら、ドナルド・トランプに近い人々は、今月初めにFBIによって家宅捜索された彼のMar-a-Lago財産からの映像を公開するよう彼に勧めています. 前大統領はテープを公開するかどうかを確認していませんが、息子はフォックス・ニュースにそうなるだろうと語った.

Andor は、他の Star Wars ショーから大きな距離を置きます。

Andor は、他の Star Wars ショーから大きな距離を置きます。

アンドールの一場面。数十年前、ジョージ・ルーカスがスター・ウォーズのテレビ番組を制作するのを妨げた主な理由は、お金でした。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language