web-dev-qa-db-ja.com

[[maybe_unused]]による構造化バインディング

パターンマッチングを使用する関数型言語(時々?)は、バインドされた値を無視する可能性がありますが、C++ 17構造化バインディングでは、それを行う方法がないようです( std :: ignore with構造化バインディング? =)。ダミーの名前を使用することをお勧めしますが、未使用の変数に関する警告が表示されます。

Clangとgccの両方の最新のヘッドにより、これは期待されることを実行します。

[[maybe_unused]] auto x =4 ; // fine, no warning
[[maybe_unused]] auto [a,dummyb,dummyc] = std::Tuple<int,int,float>(1,1,1.0f); 

しかし、私はこれがうまくいくことも望んでいました:

auto [g,[[maybe_unused]]dummyh,[[maybe_unused]]dymmyi] =
      std::Tuple<int,int,float>(1,1,1.0f);

特定の理由はありますか 属性 ここでは使用できませんか? (標準的にも技術的にも)。 gccもclangもこれを受け入れません。


編集し、サポート状況を収集します:( godbolt/compiler Explorer に感謝)。それは期待どおりに機能します(以前の場合もあります):

  • gcc 8.0トランク(g ++ 8.0.0 20171015試験的)
  • clang 4.0.0
  • icc 18( specs に従ってテストされていません)
  • msvc 19.22(おそらく以前)(修正、 バグレポート によると)

https://gcc.godbolt.org/z/H2duYd のgodboltで試してみてください

41
Johan Lundberg

構造バインディング紙で:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0144r2.pdf

彼らは彼らの推論について議論します:

3.8コンポーネントを明示的に無視する方法はありますか?

動機は、未使用の名前に関するコンパイラの警告を黙らせることでしょう。

答えは「まだ」ではないはずです。これはユースケースに動機付けられていません(コンパイラ警告のサイレンシングは動機付けですが、それ自体はユースケースではありません)。これは、一般的なパターンマッチングの提案の文脈でこれを再検討できるようになるまで残しておく必要があります。特別なケースとして。

Std :: tieとの対称性は、std :: ignore:

   Tuple<T1,T2,T3> f(); 
   auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element 

しかし、これは扱いにくいと感じます。

言語でのパターンマッチングを予測すると、_や*などのワイルドカードが提案される可能性がありますが、パターンマッチングがまだないため、互換性があるとわかっている構文を選択するのは時期尚早です。これは、パターンマッチングで考慮されるのを待つことができる純粋な拡張機能です。

これは[[maybe_unused]]を明示的に扱っていませんが、推論は同じであると思います。コンパイラ警告の停止はユースケースではありません。

23
Mikel F

CWG 236 の解決策として、規格の草案は次の文言( [dcl.attr.unused] )を得ました。

  1. 属性は、クラスの宣言、typedef-name、変数(構造化バインディング宣言を含む)、非静的データに適用できますメンバー、関数、列挙、または列挙子。

  2. maybe_unusedとマークされたエンティティの場合、実装は、エンティティまたはその構造化バインディング(存在する場合)が使用または未使用であることを示す警告を発行してはなりません。 maybe_unusedとマークされていない構造化バインディング宣言の場合、その構造化バインディングがすべて使用されていない限り、実装はそのような警告を出すべきではありません。

構造化バインディング宣言は、以前は明示的に言及されていませんでした。

8
metalfox