LoginSignup
1
1

More than 5 years have passed since last update.

reinterpret_castとかを使って構造体をtupleに変換する(追記:できなかった)

Last updated at Posted at 2017-01-07

追記

やらないほうがいいようです
https://twitter.com/amedama41/status/817934240360763393
※strict aliasing:コンパイラ的に許可されていない型の間でポインタを通じて行ったり来たり弄ったりすると不思議な力で悲しいことになる。詳しくはググって

------追記ここまで------

目的

構造体をtupleに変換したい
ユーザー定義の構造体に対し、メモリ的に同じレイアウトでtupleに変換可能な構造体を作り、それにユーザー定義構造体をreinterpret_castすることで比較的簡単に自動生成実装できるのではないかと考えてみる
結論から言うとこの方法はそこまで筋がよいわけではなかった

考え方

struct Dog
{
  int age;
  std::string name;
};

このような構造体に対し

template<class T1,class T2>
struct Foo{
  T1 x1;
  T2 x2;
};

template<class T>
auto to_tie(T&foo){
  return std::tie(foo.x1,foo.x2);
}

このような構造体を用意して

DogをFooにreinterpret_castで変換してやれば値を取り出せるのでないだろうか
その際Dogのメンバ型をFooに知らせるために何らかの方法で明記する必要があるだろう

実装

template<class T1,class T2>
struct Foo{
    T1 x1;T2 x2;
};

template<class T1,class T2>
struct foo_adapter{
    template<class T>
    static auto to_tie(T&x)
    {
        auto &foo= reinterpret_cast<Foo<T1,T2>&>(x);
        return std::tie(foo.x1,foo.x2);
    }
};
struct Dog{
    using adapt = foo_adapter<int,std::string>;
    int age;
    std::string name;
};


int main() {
    Dog dog={12,"abc"};
    auto t=Dog::adapt::to_tie(dog);
    t = std::make_tuple(36,"xyz");
    std::cout<<dog.age<<dog.name;
}

http://melpon.org/wandbox/permlink/5m5xvpxkkIBBSq85
このような感じになる
構造体を作る側としてはfoo_adapterの引数にメンバの型を列記して定義することで、つまり

using adapt = foo_adapter<int,std::string>;

の一文を追加することで構造体をtupleに変換できるだろう

ちょっとしたassert

foo_adapterの引数を間違えると悲惨なことになる。
以下のようなassert コードを仕込んでおけばコンパイル時に検出できるかもしれない

Dog t={foo.x1,foo.x2};  //型が間違っている場合コンストラクタが正常に働かない
sizeof(Foo) == sizeof(Dog)   // 当然同じサイズになるはず

ないよりましだろう

結論

Dogに

auto tie(){return std::tie(age,name);}

を書く方法と比べてやる価値があるかというと疑問が残る
ただ上のちょっとしたassertを仕込んだりfoo_adapter以外のものを使うことで挙動をswitchできたりなどの利点はちょっとありそうだ

ああ、静的リフレクションがほしい

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1