簡體   English   中英

`std :: pair``second`具有'unordered_map`樹的不完整類型

[英]`std::pair` `second` has incomplete type with `unordered_map` tree

我正在審查我的一些舊代碼,我看到代碼使用指針來實現Variant對象的樹。 它是一棵樹,因為每個Variant都可以包含Variant*unordered_map

我查看了代碼,並想知道為什么不只是使用值, std::vector<Variant>std::unordered_map<std::string, Variant> ,而不是Variant*

所以我繼續改變它。 看起來好像除了一件事,我有錯誤

 /usr/local/include/c++/6.1.0/bits/stl_pair.h:153:11: error: 'std::pair<_T1, _T2>::second' has incomplete type _T2 second; /// @c second is a copy of the second object ^~~~~~ main.cpp:11:8: note: forward declaration of 'struct Variant' struct Variant ^~~~~~~ 

所以我想我可以欺騙編譯器延遲知道那種類型的需要,這種方式也不起作用

工作不工作! MCVE

我認為這工作得早,但實際上沒有,我忘了::typeusing HideMap...using HideMap...

#include <vector>
#include <unordered_map>
#include <iostream>

template<typename K, typename V>
struct HideMap
{
    using type = std::unordered_map<K, V>;
};

struct Variant
{
    using array_container = std::vector<Variant>;

    // Does not work either
    using object_container = typename HideMap<std::string, Variant>::type;

    // Fails
    //using object_container = std::unordered_map<std::string, Variant>;

private:
    union Union
    {
        std::int64_t vint;
        array_container varr;
        object_container vobj;

        // These are required when there are union
        // members that need construct/destruct
        Union() {}
        ~Union() {}
    };

    Union data;
    bool weak;
};

int main()
{
    Variant v;
    std::cout << "Works" << std::endl;
}

所以,我的問題是,為什么它適用於vector而不是unordered_map

如果問題是無法使用不完整類型,是否有辦法延遲unordered_map的實例化? 我真的不希望每個對象屬性都是一個單獨的new分配。

這使用placement new來將Union的初始化推遲到Variant是完整類型的構造函數。 您需要在需要使用Union任何地方reinterpret_cast 我努力不違反任何嚴格的協議。

#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>

struct Variant {
    Variant();
    ~Variant();

    private:
    std::aligned_union<0, std::vector<Variant>,
                         std::unordered_map<std::string, void *>,
                         std::int64_t>::type data;
};

namespace Variant_detail {
    using array_container = std::vector<Variant>;
    using object_container = std::unordered_map<std::string, Variant>;

    union Union {
        std::int64_t vint;
        array_container varr;
        object_container vobj;

        // These are required when there are union
        // members that need construct/destruct
        Union() {}
        ~Union() {}
    };
}

Variant::Variant() {
    //make sure that std::unordered_map<std::string, Variant> is not too large
    static_assert(sizeof(std::unordered_map<std::string, Variant>) <=
                      sizeof data, "Variant map too big");
    static_assert(alignof(std::unordered_map<std::string, Variant>) <=
                      alignof(decltype(data)), "Variant map has too high alignment");
    auto &my_union = *new (&data) Variant_detail::Union;
    my_union.vint = 42;
}

Variant::~Variant() {
    reinterpret_cast<Variant_detail::Union &>(data).~Union();
}

int main() {
    Variant v;
    std::cout << "Works" << std::endl;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM