14

タプルの疑似メンバーのレイアウトとメモリアライメントに関する正式な仕様はありますか?

タプル内の型のメモリアライメントを変更する方法はありますか?#pragma pack()ディレクティブの影響を受けますか?

例えば:

typedef std::tuple<uint8_t, uint32_t> myTuple;

これが次と同じようにメモリにあるという仕様はありますか?

#pragma pack() // Default packing
struct myStruct
{
    uint8_t first;
    uint32_t second;
}

これがばかげた質問である場合はお詫びしますが、テンプレートに関しては、配置について完全には理解していません。

編集:私が達成しようとしていることの例

現在、私は次のようなものを持っています...

#pragma pack(push)
#pragma pack(4)
struct cTriangle
{
    uint32 Index[3];
};
#pragma pack(pop)

template <class T>
inline bool Read(cFileStream& fStream, std::vector<T>& vec)
{
    if (!vec.size())
        return true;

    // fStream.Read(void* pBuffer, size_t Size)
    // Just a wrapper around a binary ifstream really
    return fStream.Read(&vec[0], sizeof(T) * vec.size());
}

std::vector<cVector3> vPoint;
vPoint.resize(Verticies);
bool result = Read(FileStream, vPoint);

メタプログラミングの目的でtypedefを実行したい場合でも、タプルのrawメモリ(したがってタプルのベクトル)に対して読み取り/書き込みを行うことができますか、それともそのメモリの配置が不明ですcTriangleか?std::tuple<uint32, uint32, uint32>

4

3 に答える 3

15

オブジェクトを特定の方法で配置する必要がないだけでなく、多くのtuple実装では、実際には2番目のオブジェクトを最初のオブジェクトの前に配置します。

于 2013-01-30T05:09:08.740 に答える
14

タプルは通常、標準レイアウトではありません。標準レイアウトクラスは、非静的データメンバーを持つ継承階層に最大で1つのクラスを持つことができ、可変個引数を実装する一般的な方法tupleは、再帰継承を介して、再帰の各レベルで1つのデータを追加することです。メンバー。これにより、tuple実装は、メンバーが使用できない空の基本クラスの最適化を通じて、個別の空のメンバーを排除できますstruct

これをチェックするとsizeof(myTuple) == sizeof(myStruct)、タプルのメモリレイアウトに構造体の要素が(一貫した)順序で含まれていると想定する権利が合理的にありますが、実際にエイリアシングをそれに依存すると、未定義の動作が発生する可能性があります。

メタプログラミングにエイリアスが必要な場合は、 Boost.Fusiontupleなどのメタプログラミングライブラリを使用することをお勧めします。このライブラリを使用すると、構造体タイプにそのメンバーで注釈を付けることができます。

#pragma pack(push)
#pragma pack(4)
struct cTriangle {
    uint32 Index[3];
};
#pragma pack(pop)
BOOST_FUSION_ADAPT_STRUCT(
    cTriangle,
    (uint32[3], Index))
于 2013-01-30T16:30:51.230 に答える
1

デビッドが指摘するように、基準による保証はありません。ただし、2つの値のタプルに関心がある場合は、を使用することをお勧めしますstd::pair<T1, T2>。これは、標準レイアウト(標準レイアウトT1,T2の場合)であり、予測可能なメモリレイアウトを備えています。

C++0xタプルが要素を後方に格納するも参照してください。

[編集]

申し訳ありませんが、あなたのコメントに答える前に、私はecatmurの答えを見ていませんでした。ちなみに、構造体のすべてのメンバーが同じタイプの場合は、もちろんstd :: arrayを使用できます。これは標準のレイアウトであり、std::tupleと同様にstd::getで要素にアクセスできます。

于 2013-01-30T14:35:24.550 に答える