C ++ 17およびC ++ 2a:IssacuaでのISO会議からのニュース

11月初旬、米国のイサクア市で、標準化C ++に関する国際ワーキンググループWG21の会議が終了し、 Yandexの従業員が参加しました 。 会議では、C ++ 17を「洗練」し、範囲、コルーチン、リフレクション、契約などについて議論しました。



ミーティングはいつものように1日かかりましたが、C ++ 17の作業時間を増やすために、昼休みを30分短縮することが決定されました。



ほとんどの場合、ドラフトC ++ 17の欠点の分析に専念しているという事実にもかかわらず、私たちはいくつかの興味深い新鮮なアイデアを議論することに成功しました



デブリーフィング



過去(および次の会議)の主なタスクは、C ++ 17のコメントの分析と修正です(C ++ 17の主要な革新に気付いていない場合はここにあります )。 コメントには、WG21加盟国からのコメントと、標準ライブラリのユーザー/開発者からのコメントの2種類がありました。 従来、国からのコメントは最初に整理されます(各コメントには、国コードと順次増加するコメント番号で構成される識別子が割り当てられます)。 今回は300以上のコメントが届きました。 最も興味深い思い出に残るものを以下に示します。



RU 1:定数オブジェクトの初期化



2000年以降のC ++では、定数構造の初期化に問題があります。 そのため、コンパイラの動作は突然、完全に自明でない多くの要因に依存します。



struct A0 {}; const A0 a0; //   struct A1 { A1(){} }; const A1 a1; // OK struct A2 { int i; A2(): i(1) {} }; const A2 a2; // OK struct A3 { int i = 1; }; const A3 a3; //  
      
      





この振る舞いを修正するリクエストは、Ivan Lezhankinからcpp-proposals@yandex-team.ruに寄せられ、GOSTの人々を使用して、国からのコメントとして設計し、C ++ 14およびC ++ 17の振る舞いを修正しました。 これで、上記のコードがコンパイルされます。



役に立つ場合:

リファクタリング時に非常に便利です。 前に空のコンストラクタを削除すると、プロジェクトのコンパイルが壊れる可能性があります。



 //   : struct A1 { A1(){} //  ,    }; //      const A1 a1;
      
      





固定されたRU 1では、空のコンストラクターを削除することでクラスを変更でき、コードは引き続き機能します。 同時に、わずかなパフォーマンスの向上を得ることができます。メタプログラミングを使用するライブラリには、std :: is_trivially_constructibleのクラスに対する追加の最適化が含まれることがあります。 コンパイラは、多くの場合、コンパイラ自身が生成したコンストラクタなどの最適化に優れています。



RU 2:型特性の無効な使用



失血に気づかずに死ぬのではなく、足で自分自身を撃つ素晴らしい方法:



 #include <type_traits> struct foo; // forward declaration void damage_type_trait() { //  is_constructible   ,  . //        //   ,       . std::is_constructible<foo, foo>::value; } struct foo{}; int main() { static_assert( //   ,   damage_type_trait() //  std::is_constructible std::is_constructible<foo, foo>::value, "foo must be constructible from foo" ); }
      
      





個人的には、boost :: variantで同様のエラーを探すのに1週間を費やしました。 WG21はこの問題に気付き、修正に取り組んでいます。 C ++ 17が修正され、無効なtype_traitsのコードを見ると、コンパイラは問題の原因を詳述するメッセージとともにコンパイルエラーをスローする可能性があります。



役に立つ場合:

間違いを見つけにくくするのに役立ちます。 デザイナーがtype_traitsを使用するオプションとバリアントを使用する場合、多くの不快な驚きから開発者を救います。



RU 4およびUS 81:constexpr char_traits



私たちと米国は同じ欠陥を発見しました。 問題は、std :: string_viewにはconstexprコンストラクターがありますが、オブジェクトの初期化は動的に行われることです。



 #include <string_view> //  : // > error: constexpr variable 'service' must be initialized by a constant expression // > constexpr string_view service = "HELLO WORD SERVICE"; // > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // > string_view:110:39: note: non-constexpr function 'length' cannot be used // constexpr string_view service = "HELLO WORD SERVICE";
      
      





修正として、修正を行いました(バージョンバージョンp0426r1が採用されました。一般的な使用にはまだ対応していません)。



役に立つ場合:

コンパイラーは、std :: string_viewの構成をより最適化できます。constexpr式でstring_viewを使用できます。



shared_ptr ::ユニーク()



要求の1つは、shared_ptr :: unique()がstd :: memory_order_acquireのメモリ同期を保証することでした。



そして、マルチスレッド環境でこの機能を使用する方法を知らない人が多いことに気付きました。 したがって、正しい使用法は使用することではありません。



shared_ptr :: unique()がtrueを返し、実装がstd :: memory_order_seq_cstを保証する場合、...それは何も意味しない! unique()関数を呼び出した直後に状況が変わる場合があります。





その結果、unique()メソッドを非推奨としてマークし、shared_ptr :: use_count()の説明ですべての問題をより詳細に説明することが決定されました。



ルジャンドル関数の関連多項式



Matvey Kornilovのモスクワ州立大学からcpp-proposals@yandex-team.ruに寄せられた1つのリクエストは、特に記憶に残っています。 数学に関連する多くの興味深いことを説明しました。 いくつかのアイデアは現在著者自身によって開発されており、一部は標準への「編集上の変更」として送信され、標準編集者の1人と話し合ってIssakuaの会議で修正されました。



そのため、特に覚えている変更の1つは、「ルジャンドルpolynomial多項式」セクションの名前を変更する必要があることです。 セクションの式は多項式として表現できないためです:-)



...
C ++標準は、世界中の専門家によって開発された深刻な国際文書であり、各単語は最も正確な方法で選択されるべきであり、わずかな論理的矛盾さえも除外されるべきです。



なぜこの「学校」の間違いが私をさらに笑顔にするのか:-)



その他





議論とアイデア



いつものように、議論と報告はいくつかのサブグループで同時に行われました。 一度に5か所にいるのは難しいタスクです。そのため、すべてのアイデアをじかに伝えることはできません。 私たちが訪れた最も興味深い議論は次のとおりです。



??? 演算子()???



代替構文と演算子へのアプローチについて説明しました。

古い構文P0416R1 新しいP0352R0構文
 template<class X> class Ref { X* p; public:​ explicit Ref(int a): p(new X{a}) {} ~Ref() { delete p; } operator. X&() { return *p; } }; struct Y { Y(int); void f(); }; Ref<Y> r {99}; rf(); // (r.operator.()).f() Y &yr = r; // ??? // O_O static_assert(sizeof(Ref<Y>) == sizeof(X));
      
      



 template<class X> class Ref : public using​ X { X* p; operator X&() { return* } public:​ explicit Ref(int a): p(new X{a}) {} ~Ref() { delete p; } }; struct Y { Y(int); void f(); }; Ref<Y> r {99}; rf(); // (r.operator Y&()).f() // Error: conversion function is private Y &yr = r; // Ref<Y> constains only Y* static_assert(sizeof(Ref<Y>) == sizeof(Y*));
      
      





つまり、演算子の代わりに、もう少し理解しやすい「クラスの作成者がオブジェクト自体を処理する継承」を使用することが提案されています。 WG21は、著者にこの方向でさらに作業するように依頼しました。



演算子<=>()



operator <=>()または「operator spaceship」は、比較演算子の自動生成の議論から生まれたアイデアです。 委員会は、デフォルトで比較演算子の生成を開始することと、bool operator <(const foo&、const foo&)= default;。という形式の構造を使用して比較演算子を生成することに反対でした。 その後、アイデアの副次的に生まれました:





これまでのところ、議論はこれ以上進んでいませんが、有望に見えます。



反射



C ++のコンパイル時リフレクションを開発しているグループが会いました。 基本機能を備えており、他のサブグループへのさらなる議論のために転送する準備がほぼ整っており、TS(技術仕様)の形式でリリースする準備ができています-ユーザーはメイン標準の新しいバージョンを待たずに実験を開始できます。



まとめ



会議の人々は、規格に関する膨大な数のコメントを処理しました。 100以上のバグが修正されました。



12月5日、モスクワで、ロシアのWG21と 、標準libc ++ライブラリの開発者、Boost.Algorithmの開発者であるWG21 C ++のライブラリワーキンググループの議長であるMarshall Clowとの会議を待っています。 会議では、今後の計画と開発についてお話します。C++について質問したり、C ++ 2aのアイデアを提供したりできます。 マーシャルは未定義の動作について話します。



また、 stdcpp.ruワーキンググループの公式サイトをご紹介し 、標準化のアイデアについて議論し、提案書の作成を支援します。 これで、C ++標準に含めるアイデアを共有し、他の人がそれについてどのように考えているかを見つけ、他の開発者が提案したアイデアについて話し合うことができます。 ようこそ



All Articles