第320章 クラスにおける制約

構造化束縛は便利そうに見えますが、制約はもちろんあります。

複雑なクラス型に対して使えないか調べてみましたが、サポートしているのは本当にシンプルなクラス型だけのようです。

例えば以下の3つのケースでは構造化束縛は機能しません。

以下のソースコードは動作しないことをチェックしています。(コンパイルは通りません)

注記

マクロについては クロスコンパイルのための組み込みマクロ を参照くださいね。

main.cpp. 

    1 #if __cplusplus < 201703L
    2 # pragma message "-std=c++17を指定してください"
    3 #endif
    4
    5 struct Foo {
    6   int a;
    7   struct {
    8     int b;
    9   };
   10 };
   11
   12 struct PS {
   13   PS(int a,int b) : M_a_{a}, M_b_{b} {}
   14   int M_a_;
   15 private:
   16   int M_b_;
   17 };
   18
   19 struct base { int x; };
   20
   21 struct derived : public base
   22 { int y; };
   23
   24 int main()
   25 {
   26   Foo f{1,2};
   27   PS p{1,2};
   28   derived d{1,2};
   29
>> 30   auto [a] = f;
>> 31   auto [c,d] = p;
>> 32   auto [e] = d;
   33
   34   return 0;
   35 }

これを gcc でコンパイルしようとすると怒られます。

$ g++ main.cpp -std=c++17
main.cpp: In function ‘int main()’:
main.cpp:30:7: error: cannot decompose class type ‘Foo’ because it has an anonymous struct member
  auto [a] = f;
       ^~~
main.cpp:7:2: note: declared here
  struct {
  ^~~~~~
main.cpp:31:11: error: conflicting declaration ‘auto d’
  auto [c,d] = p;
           ^
main.cpp:28:10: note: previous declaration as ‘derived d’
  derived d{1,2};
          ^
main.cpp:32:7: error: cannot decompose class type ‘derived’: both it and its base class ‘base’ have non-static data members
  auto [e] = d;
       ^~~

まずは無名クラスですね。

    1 struct Foo {
    2   int a;
    3   struct {
    4     int b;
    5   };
    6 };
   22   Foo f{1,2};
>> 26   auto [a] = f;

このように展開する再、 Foo クラス内に無名クラスが入っているとコンパイラに怒られます。

次のプライベートメンバーの展開は特に気をつけたいです。

   12 struct PS {
   13   PS(int a,int b) : M_a_{a}, M_b_{b} {}
   14   int M_a_;
   15 private:
   16   int M_b_;
   17 };
   27   PS p{1,2};
>> 31   auto [c,d] = p;

メンバー変数が隠蔽されてるだけでコンパイルエラーになるので、これは結構厳しい制約ですよね。

最後は継承をしているオブジェクトの展開です。

   19 struct base { int x; };
   20
   21 struct derived : public base
   22 { int y; };
   28   derived d{1,2};
>> 32   auto [e] = d;

継承を良く使う人にとっては悪いニュースかもしれないです…

(´・ω・`)

Copyright 2017-2018, by Masaki Komatsu