嵌套的hashmap初始化列表

时间:2014-05-06 21:46:06

标签: c++ hashmap visual-studio-2013 initializer-list

我尝试使用std::hash_map来定义嵌套对象。我使用的是Visual Studio 2013。

当我尝试使用嵌套的初始化文字时,麻烦就开始了。我已经减少了以下方法:

enum ENUM1 {
    ENUM1_A,
    ENUM1_B,
};

enum ENUM2 {
    ENUM2_A,
    ENUM2_B
};

enum ENUM3 {
    ENUM3_A,
    ENUM3_B
};

std::hash_map<ENUM1, std::hash_map<ENUM2, std::hash_map<ENUM3, int>>> A = {
    {
        ENUM1_A, {
            {   
                ENUM2_A, {
                    { ENUM3_A, 123 },
                    { ENUM3_B, 45 },
                },
            },
            {
                ENUM2_B, {
                    { ENUM3_A, 733 },
                    { ENUM3_B, 413 },
                }
            }
        }
    }
};

编译器没有抱怨,但在执行时会导致访问冲突和以下调用堆栈:

    ***.exe!std::list<std::pair<enum ENUM3 const ,int>,std::allocator<std::pair<enum ENUM3 const ,int> > >::clear() Line 1503   C++
    ***.exe!std::list<std::pair<enum ENUM3 const ,int>,std::allocator<std::pair<enum ENUM3 const ,int> > >::_Tidy() Line 1884   C++
    ***.exe!std::list<std::pair<enum ENUM3 const ,int>,std::allocator<std::pair<enum ENUM3 const ,int> > >::~list<std::pair<enum ENUM3 const ,int>,std::allocator<std::pair<enum ENUM3 const ,int> > >() Line 1096  C++
    ***.exe!std::_Hash<stdext::_Hmap_traits<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> >,0> >::~_Hash<stdext::_Hmap_traits<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> >,0> >() Line 409 C++
    ***.exe!stdext::hash_map<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> > >::~hash_map<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> > >() C++
    ***.exe!std::pair<enum ENUM2 const ,stdext::hash_map<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> > > >::~pair<enum ENUM2 const ,stdext::hash_map<enum ENUM3,int,stdext::hash_compare<enum ENUM3,std::less<enum ENUM3> >,std::allocator<std::pair<enum ENUM3 const ,int> > > >()  C++
    ***.exe!`dynamic initializer for 'A''() Line 76 C++

不幸的是,我对C ++很陌生,并且不知道自己要做些什么。

我已经看到the following question答案引用了编译器错误,但链接的错误报告明确提到此问题与字符串文字有关。

我做错了什么?有点无关,是什么阻止了这样一个具有这样的常量值的对象在编译时被计算出来?有没有更好的方法在代码中定义类似JSON的对象?

1 个答案:

答案 0 :(得分:4)

MSVC2013中有许多(好的,至少3个)与初始化列表和统一初始化相关的侵入性错误。

  

更新根据评论,VS13 Update 2中删除了此特定错误。

可悲的是,建议是......暂时远离他们中的许多人。我记住以下规则:

  • 在任何具有构造函数的类型上获取初始化列表(如所有标准容器)始终显式命名类型(IOW不要使用匿名统一初始化程序语法)

连接错误:

对于它的价值,以下标准库代码是gcc / clang上的公平游戏: Live On Coliru

以下是我为MSVC推荐的措辞(我现在无法对其进行测试,因为我没有方便的窗盒):

#include <unordered_map>

enum ENUM1 { ENUM1_A, ENUM1_B }; 
enum ENUM2 { ENUM2_A, ENUM2_B }; 
enum ENUM3 { ENUM3_A, ENUM3_B }; 
namespace std {
    template <> struct hash<ENUM1> : std::hash<int> {};
    template <> struct hash<ENUM2> : std::hash<int> {};
    template <> struct hash<ENUM3> : std::hash<int> {};
}

int main() {
    using Map3 = std::unordered_map<ENUM3, int>;
    using Map2 = std::unordered_map<ENUM2, Map3>;
    std::unordered_map<ENUM1, Map2> A = {
        {
            ENUM1_A, Map2 {
                {
                    ENUM2_A, Map3 {
                        { ENUM3_A, 123 },
                        { ENUM3_B, 45 },
                    },
                },
                {
                    ENUM2_B, Map3 {
                        { ENUM3_A, 733 },
                        { ENUM3_B, 413 },
                    }
                }
            }
        }
    };
}