0

「TinyTemplateLibrary」のバリアント型を使用しています。バリアントは次のように定義されます。

template< TTL_TPARAMS_DEF(TTL_MAX_TYPELIST_PARAMS, empty_type) >
struct variant
{
    typedef variant this_t;
    typedef meta::typelist< TTL_ARGS(TTL_MAX_TYPELIST_PARAMS) > list;
    ...

    template< typename T >
    variant( const T& r ) : which_(0), pnt_(0)
    {
        typedef meta::find_equivalent_type<const T&, list> found;
        pnt_ = new(stor_.buf_) ttl::data_holder<typename found::type>(r);
        which_ = found::index;
    }
    ...
private:
    template<int N> 
    struct storage
    {
        union
        {
            ttl::data_holder_base dummy;  //hope to satisfy alignment settings
            char buf_[N];
        };
    };

    int which_;
    ttl::data_holder_base* pnt_;
    storage< sizeof(ttl::data_holder<typename list::largest_type>) > stor_;
    ....
};


struct data_holder_base {};

template< typename T >
struct data_holder : data_holder_base
{
    ...
    typedef const T& param_type;

    T d;
    ...
    data_holder( param_type d_ ) : d(d_) {}
    ...
};

このタイプのオブジェクトをネットワーク経由で送信し、「memcpy」を使用して「再構築」すると、ポインター「pnt_」がニルヴァーナを指すことは明らかです。保存されているタイプがわかっているため、キャストを使用してポインタ「pnt_」を再構築しようとしています。

template<typename T>
inline void rebuild()
{
    pnt_ = reinterpret_cast<ttl::data_holder<T>*>(stor_.buf_); 
}

この例を確認した場合は、機能します。pnt_ = new(stor_.buf_) ...しかし、配置new( )がオブジェクトをにどのように配置しているかはわかりませんstor_.buf_std::distance(&stor_.buf_[0], pnt_)オブジェクトを見つけるようなものを保存する必要がありますか?

または、元にpnt_戻す別の方法はありますか?

マリオありがとう

4

1 に答える 1

0

配置newは新しいオブジェクトを配置します。stor_.buf_これは、配置newが機能するように定義されているためです。使用するnewメモリのアドレスを指定すると、その場所にオブジェクトが構築されます。まったく同じアドレスを返すため、 に格納されているアドレスは のアドレスになりpnt_ますが、 ではなくstor_.buf_、構築されたオブジェクトの型が になります。アドレスが同じであるため、言及する値は常にゼロになります (呼び出しがコンパイルされると仮定すると、引数の型が異なるためコンパイルされません)。ttl::data_holder<found::type>char*std::distance

のアドレスstor_.buf_も常に のアドレスと等しくなりstor_.dummyます。pnt_次のように割り当てることで、追加したコードをより簡単にすることができます。

pnt_ = &stor_.dummy;

ただし、ソケットを介して未加工のメモリをコピーしたように見えるため、このvariantオブジェクトの内部を修正することは氷山の一角にすぎません。バリアントが保持する値にはアドレス含まれている可能性があり、その中に到達する方法はありません。その場合でも、必要なアドレスが利用できない場合があります。variant修正しているアドレスがたまたま同じオブジェクト内のアドレスであることは幸運だったので、計算は簡単です。しかしstd::string、フリー ストアからメモリを割り当てる を考えてみましょう。ソケットを介して送信しても、相手側で使用できるものは何も提供されません。文字データさえ提供されない可能性があります。代わりに、シリアル化および逆シリアル化のための他の手法を追求する必要がありますttl::variantオブジェクト。Stack Overflow に質問を投稿して、その方法を尋ねることができます。

于 2012-05-22T18:54:12.617 に答える