読者です 読者をやめる 読者になる 読者になる

茂加部珈琲店

主にtech関連のメモ置き場です

無名共用体、構造体とスマートポインタ

最近C++を勉強中の私です.
今日は無名構造体とスマートポインタを使ったコードが上手くいかなかったので、反省として残しておきます.

例えば、以下のようなコードを書いたとします.

template <typename T>
struct test{
    union{
        struct{std::unique_ptr<T> x,y,z;};
        //etc.
    };

    test(T _x, T _y,T _z){
        x = std::make_unique<T>(_x);
        y = std::make_unique<T>(_y);
        z = std::make_unique<T>(_z);
    }
  
};

こういった書き方は、ベクトルクラスを作ったりするときに便利ですよね
しかし、このような書き方は「行儀の良い」クラスにしかできないみたいです.
この構造体の初期化を行うコードをclangでコンパイルすると、こんなエラーが出ます

error: attempt to use a deleted function
    test<int> t = {1,2,3};
              ^
note: destructor of 'test<int>' is implicitly deleted because variant field '' has a non-trivial destructor
    struct{std::unique_ptr<T> x,y,z;};
    ^

どうやら、デストラクタを生成できないためスマートポインタは無名構造体には入れてはいけないようです.まだ良くわかってない気がしますが...
ところで、これをg++でコンパイルするとどうなるでしょうか?

segfaultで落ちます

ここでは何のエラーも表示されませんので、g++だけを使うと小一時間悩む羽目になります.
gdbはexceptionを検出してくれますが、ライブラリの奥深くに飛ばされて更に混乱するだけです.
エラーが良くわからない場合は別のコンパイラを試してみようね!という教訓でした. ..あときちんとC++を勉強しよう!

こういう構造をガンガン使ってそうなglm(OpenGL Mathematics)がどのように対処してるのか見ようと思いましたが、ソースコードを見て目が回ってしまいました...
勉強しながら読んでみたいと思います