C ++ 11ではどのような重大な変更が導入されていますか?

228
R. Martinho Fernandes 2011-06-19 13:48.

古いコードのコンパイルを停止させるC ++ 11の変更の少なくとも1つはexplicit operator bool()、標準ライブラリでの導入、の古いインスタンスの置き換えですoperator void*()。確かに、これが壊れるコードはおそらくそもそも有効であるべきではなかったコードですが、それでもなお壊れる変更です。以前は有効だったプログラムはもはやそうではありません。

他に重大な変更はありますか?

9 answers

178
Johannes Schaub - litb 2011-06-20 01:47.

FDISには、付録C.2「C ++およびISOC ++ 2003」に非互換性に関するセクションがあります。

要約すると、ここでFDISを言い換えると、SOの回答として(より適切に)適したものになります。違いを説明するために、私自身の例をいくつか追加しました。

ライブラリに関連する非互換性がいくつかあり、その意味が正確にわからないため、他の人に詳しく説明してもらいます。

コア言語


#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"

#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .

新しいキーワード:alignas、alignof、char16_t、char32_t、constexpr、decltype、noexcept、nullptr、static_assert、thread_local


longで表すことができるよりも大きい特定の整数リテラルは、符号なし整数型から符号付きlonglongに変更される可能性があります。


整数除算を使用する有効なC ++ 2003コードは、結果を0または負の無限大に丸めますが、C ++ 0xは常に結果を0に丸めます。

(確かに、ほとんどの人にとって実際には互換性の問題ではありません)。


キーワードautoをストレージクラス指定子として使用する有効なC ++ 2003コードは、C ++ 0xでは無効である可能性があります。


変換を絞り込むと、C ++ 03との非互換性が発生します。たとえば、次のコードはC ++ 2003では有効ですが、doubleからintへの変換はナローイング変換であるため、この国際標準では無効です。

int x[] = { 2.0 };

暗黙的に宣言された特別なメンバー関数は、暗黙の定義が不正な形式であった場合に削除されたものとして定義されます。

定義が不要なコンテキスト(たとえば、評価されない可能性のある式)でこれらの特別なメンバー関数の1つを使用する有効なC ++ 2003プログラムは、形式が正しくありません。

私の例:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }

このようなsizeofトリックは、一部のSFINAEで使用されており、今すぐ変更する必要があります:)


ユーザーが宣言したデストラクタには、暗黙の例外仕様があります。

私の例:

struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }

このコードはterminateC ++ 0xで呼び出しますが、C ++ 03では呼び出しません。A::~AC ++ 0xでの暗黙の例外仕様はnoexcept(true)です。


を含む有効なC ++ 2003宣言exportは、C ++ 0xでは不正な形式です。


>直後に別の式が続く有効なC ++ 2003式は、>2つのテンプレートを閉じるものとして扱われるようになりました。

C ++ 03では、>>常にシフト演算子トークンになります。


内部リンケージを持つ関数の依存呼び出しを許可します。

私の例:

static void f(int) { }
void f(long) { }

template<typename T>
void g(T t) { f(t); }

int main() { g(0); }

C ++ 03では、これはを呼び出しますf(long)が、C ++ 0xでは、これはを呼び出しますf(int)。C ++ 03とC ++ 0xの両方で、次の呼び出しに注意する必要がありますf(B)(インスタンス化コンテキストは、外部リンケージ宣言のみを考慮します)。

struct B { };
struct A : B { };

template<typename T>
void g(T t) { f(t); }

static void f(A) { }
void f(B) { }

int main() { A a; g(a); }

f(A)外部リンケージがないため、より適切なマッチングは行われません。


ライブラリの変更

C ++ 0xのC ++標準ライブラリに追加された識別子を使用する有効なC ++ 2003コードは、この国際標準でのコンパイルに失敗したり、異なる結果を生成したりする場合があります。


#includes新しいC ++ 0x標準ライブラリヘッダーの名前を持つヘッダーがこの国際標準では無効である可能性がある有効なC ++ 2003コード。


スワップが含まれることを期待してコンパイルされた有効なC ++ 2003コードには<algorithm>、代わりに含める必要がある場合があります<utility>


グローバル名前空間posixは、標準化のために予約されています。


有効なC ++定義があること2003コードoverridefinalcarries_dependency、またはnoreturnマクロなどのC ++ 0xのでは無効です。

28
arsenm 2011-06-19 14:00.

autoキーワードの意味が変わりました。

24
Downvoter 2011-06-19 13:54.

大きな変化?

ええと、一つdecltypeconstexprnullptr、識別子として、、などを使用した場合、問題が発生する可能性があります...

21
Johannes Schaub - litb 2011-06-20 02:42.

非互換性のセクションでカバーされていないいくつかのコアの非互換性:


C ++ 0xは、挿入されたクラス名を、名前がテンプレートテンプレートパラメーターへの引数として渡される場合はテンプレートとして扱い、テンプレートタイプパラメーターに渡される場合はタイプとして扱います。

これらのシナリオでは、挿入されたクラス名が常に型であることに依存している場合、有効なC ++ 03コードの動作が異なる場合があります。私のclangPRから取得したサンプルコード

template<template<typename> class X>
struct M { };

template<template<typename> class X>
void g(int = 0); // #1

template<typename T>
void g(long = 0); // #2

template<typename T>
struct A {
  void f() {
    g<A>(); /* is ambiguous in C++0x */
    g<A>(1); /* should choose #1 in C++0x */
  }
};

void h() {
  A<int> a;
  a.f();
}

C ++ 03では、コードは2番目のg時間を両方とも呼び出します。


C ++ 0xにより、C ++ 03で依存していた一部の名前が非依存になります。また、現在のクラステンプレートのメンバーを参照する非依存修飾名の名前ルックアップをインスタンス化時に繰り返す必要があり、これらの名前がテンプレート定義コンテキストで行われるのと同じ方法でルックアップすることを確認する必要があります。

この変更により、ドミナンスルールに依存する有効なC ++ 03コードがコンパイルされなくなる可能性があります。

例:

struct B { void f(); };

template<typename T>
struct A : virtual B { void f(); };

template<typename T>
struct C : virtual B, A<T> {
  void g() { this->f(); }
};

int main() { C<int> c; c.g(); }

呼び出すこの有効なC ++ 03コードA<int>::fは、C ++ 0xでは無効です。これは、インスタンス化時の名前ルックアップがではなく検索A<int>::fされB::f、定義時ルックアップとの競合が発生するためです。

現時点では、それがFDISの欠陥であるかどうかは明らかではありません。委員会はこれを認識しており、状況を評価します。


最後の部分が基本クラスを示す修飾名の修飾子の最後の部分の識別子と同じであるusing宣言。using宣言は、その名前のメンバーではなく、コンストラクターに名前を付けるようになりました。

例:

struct A { protected: int B; };
typedef A B;

struct C : B {
  // inheriting constructor, instead of bringing A::B into scope
  using B::B;
};

int main() { C c; c.B = 0; }

上記のサンプルコードはC ++ 03では整形式ですが、C ++ 0xでは整形式でA::Bはなく、でアクセスできませんmain

14
Lightness Races in Orbit 2013-10-23 06:25.

ストリーム抽出の失敗は別の方法で処理されます。

#include <sstream>
#include <cassert>

int main()
{
   std::stringstream ss;
   ss << '!';
   
   int x = -1;
   
   assert(!(ss >> x)); // C++03 and C++11
   assert(x == -1);    // C++03
   assert(x == 0);     // C++11
}

提案の変更

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23

標準リファレンス

[C++03: 22.2.2.1.2/11]: ステージ2の処理の結果は、次のいずれかになります。

  • 一連の文字がステージ2に蓄積され、(の規則に従ってscanf)タイプの値に変換されvalます。この値はに格納されvalios_base::goodbitに格納されerrます。
  • ステージ2で蓄積された一連の文字によりscanf、入力の失敗が報告されます。ios_base::failbitに割り当てられerrます。[ed:何も保存されていませんval。]

[C++11: 22.4.2.1.2/3]: [..]格納する数値は次のいずれかになります。

  • 変換関数がフィールド全体の変換に失敗した場合はゼロios_base::failbitに割り当てられerrます。
  • フィールドがで表すには大きすぎる正の値を表す場合、最も正の表現可能な値valios_base::failbitに割り当てられerrます。
  • フィールドがで表すには大きすぎる負の値を表す場合は、最も負の表現可能な値、または符号なし整数型の場合はゼロvalios_base::failbitに割り当てられerrます。
  • それ以外の場合は、変換された値。

結果の数値はに格納されvalます。

実装

  • GCC4.8 はC ++ 11に対して正しく出力します:

    アサーション `x == -1 'が失敗しました

  • GCC4.5-4.8 はC ++ 03のすべての出力で、バグのように見えます。

    アサーション `x == -1 'が失敗しました

  • Visual C ++ 2008ExpressはC ++ 03用に正しく出力します。

    アサーションに失敗しました:x == 0

  • Visual C ++ 2012ExpressはC ++ 11に対して誤って出力します。これは、実装ステータスの問題のように見えます。

    アサーションに失敗しました:x == 0

13
Xeo 2011-06-19 13:52.

明示的な変換演算子の導入はどのように大きな変化ですか?古いバージョンは、以前と同じように「有効」です。

はい、からoperator void*() constへの変更explicit operator bool() constは重大な変更になりますが、それ自体が間違った方法で使用されている場合に限ります。適合コードは壊れません。

さて、もう1つの重大な変更は、集計の初期化中に変換を絞り込むことを禁止することです。

int a[] = { 1.0 }; // error

編集:覚えておいてくださいstd::identity<T>。C++ 0xで削除されます(注を参照)。型を依存させるのは便利な構造体です。構造体は実際にはあまり機能しないため、これで修正されるはずです。

template<class T>
struct identity{
  typedef T type;
};
8
James McNellis 2011-06-19 14:19.

コンテナライブラリには多くの変更が加えられており、より効率的なコードが可能になりますが、いくつかのコーナーケースでは下位互換性が失われます。

たとえば、std::vectorデフォルトの構造、C ++ 0x、および重大な変更について考えてみます。

7
Ben Voigt 2011-06-19 14:15.

下位互換性を壊す暗黙の移動について多くの議論がありました

(関連する議論のある古いページ)

コメントを読んでみると、暗黙の移動リターンも重大な変更です。

6
Lightness Races in Orbit 2011-06-19 14:02.
struct x {
   x(int) {}
};

void f(auto x = 3) { }

int main() {
   f();
}

C ++ 03:有効です。

C ++ 0x: error: parameter declared 'auto'

Related questions

MORE COOL STUFF

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

驚くほど素晴らしいDropMixミュージックミキシングカードゲームは30ドルで驚くべき取引です

驚くほど素晴らしいDropMixミュージックミキシングカードゲームは30ドルで驚くべき取引です

DropMixはNFC対応のカードゲームで、基本的にはリミックスアーティストになります。現在、Amazonでは$ 30まで下がっており、これまでで最高の価格に匹敵します。ロックバンドで有名なHarmonixによって開発されたDropMixは、おそらく少し野心的すぎるように思われます。結局のところ、ほとんどの人は素晴らしいリズムを持っていませんが、ゲームは驚くほどうまく実行されます。

メアリーJ.ブライジがついにハリウッドウォークオブフェイムスターを獲得

メアリーJ.ブライジがついにハリウッドウォークオブフェイムスターを獲得

写真:APメアリーJ.ブライジは、間もなくハリウッドウォークオブフェイムのスターを獲得します。これは、メアリーJよりもハリウッドウォークオブフェイムのほうが正直なところ恩恵です。

MeltdownとSpectreの脆弱性についてこれまでに知っていることはすべて、簡単な方法で説明されています

MeltdownとSpectreの脆弱性についてこれまでに知っていることはすべて、簡単な方法で説明されています

画像:グラズ工科大学/ NataschaEiblがデザインしたロゴ。MeltdownとSpectreは、攻撃者がシステムメモリに保存されているあらゆる種類の情報にアクセスできるようにする2つの脆弱性に付けられた名前です。

彼のニューヨークの家から追い出されようとしている97歳の第二次世界大戦の獣医。メリーエフィングクリスマス

彼のニューヨークの家から追い出されようとしている97歳の第二次世界大戦の獣医。メリーエフィングクリスマス

日本人に襲われたときに真珠湾にいた97歳の第二次世界大戦のベテランが、ニューヨークのブルックリンから追い出されています。

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