4

それらの型情報を取得するために、プレーンな古いデータ型のメンバーを適切にループする方法について疑問に思っています。あれは :

struct my_pod
{
    int a;
    double b;
};

template<typename POD>
void loopOverPOD()
{
    for_each(POD, member) // The magic part
    {
        // member::type should be for my_pod int, then double
        typename member::type i;
        // member::size_of should be equal to sizeof(int) then sizeof(double)
        // Trivial if we can have member::type information.
        int size = member::size_of;
        // member::offset_of should be equal to 0, then sizeof(int)
        // Trivial if we can have member::size_of information.
        int offset = member::offset_of;
    }
}

私の知る限り、C++ では、テンプレートを使ってトリッキーな操作を行わずに簡単な型のイントロスペクションを行うことはできません。しかし、ここでは、実際にマクロを使用しても、テンプレートで具体的な解決策を見つけることができません。そして、問題は解決策の存在よりもむしろ私に関係しています。:-)

私は必ずしも邪魔にならない解決策を求めているわけではありません。

前もって感謝します。

4

3 に答える 3

4

boost.fusions ADAPT_STRUCTを使用して POD をシーケンスに変換し、その後fusions for_eachを使用して関数オブジェクトを各メンバーに適用できます。これは邪魔にならず、POD タイプは POD のままです。

良いことは、ADAPT_STRUCT マクロを構造体定義とは別の (ヘッダー) ファイルに配置し、反復が必要なコードでのみ使用できることです。

反対に、このマクロでは、メンバーの型と名前の両方を再度言及する冗長性が必要です。ある時点で、フュージョンは C++11 の機能を使用してその冗長性を取り除くことになると思います (タイプについて再度言及します)。当面の間、構造体と ADAP_STRUCT 部分を宣言するマクロを作成することができます。

于 2013-06-30T23:03:08.787 に答える
1

C++14 以降を使用している場合は、POD をループしてタイプを出力するためにBoost.Precise and Flat Reflection( https://github.com/apolukhin/magic_get/ ) を使用できます。boost::typeindex::type_id_runtime(field)

#include <iostream>
#include <boost/pfr/precise.hpp>
#include <boost/pfr/flat.hpp>
#include <boost/type_index.hpp>

struct my_pod
{
    int a;
    double b;
};

struct my_struct
{
    char c;
    my_pod pod;
};

int main() {
    my_pod val{1, 2.5};

    my_struct var{'a', 1, 2.5};

    std::cout <<  "Flat:\n";
    boost::pfr::flat_for_each_field(var, [](const auto& field, std::size_t idx) {
        std::cout << idx << ": " << boost::typeindex::type_id_runtime(field) << "; value: " << field << '\n';
    });

    std::cout <<  "\nNot Flat:\n";
    boost::pfr::for_each_field(var, [](const auto& field, std::size_t idx) {
        using namespace boost::pfr::ops;
        std::cout << idx << ": " << boost::typeindex::type_id_runtime(field) << "; value: " << field << '\n';
    });
}

この例の出力:

Flat:
0: char; value: a
1: int; value: 1
2: double; value: 2.5

Not Flat:
0: char; value: a
1: my_pod; value: {1, 2.5}

この場合、オフセットを取得する方法はわかりませんが...

于 2019-02-08T12:38:59.657 に答える