std :: map具有std :: map值的问题

时间:2015-08-07 14:38:17

标签: c++ stdmap

我想创建一个将QStrings映射到另一个std :: map的std :: map。但是,当我尝试这样做时,它似乎将它们映射到std :: _ Tree。

执行此操作的代码在这里

// *** Meta Data ****
quint8 numMetaDataItems = getBufferUint<quint8>(&frameData[numMetaDataOffset]);
size_t metaDataItemOffset = numMetaDataOffset + sizeof(numMetaDataItems);
std::map<int, QString> tempMap;

for (int i = 0; i < numMetaDataItems; i++)
{
    int metadataId = getBufferUint<quint8>(&frameData[metaDataItemOffset]);
    QString metadata = QString::fromUtf8((const char*) &frameData[metaDataItemOffset + 1]) ;
    //tempMap.insert(std::pair<int, QString>(metadataId, metadata));
    metaDataModel->metaDataMap[fileName][metadataId] = metadata;
    metaDataItemOffset += headerLength - metaDataItemOffset;
}

当我使用调试器时,地图的键是正确的,但值应该是另一个地图,而是说类std :: _ Tree&lt;&gt ;.任何人都可以解释为什么会这样吗?

编辑:

所以我意识到问题可能与地图无关。我尝试访问这里的地图:

QList<QString> strings;
for(std::map<int, QString>::iterator it = metaDataMap[frameID].begin(); it != metaDataMap[frameID].end(); it++)
{
    QString tempString = idMap[it->first] + ": " + it->second;
    strings.append(tempString);
}

但是因为地图中只有一个项目,所以.begin()和.end()是相同的,并且for循环中的代码永远不会运行。这听起来好像发生了什么?

3 个答案:

答案 0 :(得分:2)

this 'doc'所述,

  

地图通常用红黑树实现。

这意味着,在你的编译器中std :: map&lt;&gt;本质上是一个typedefed _Tree&lt;&gt;上课,所以没有错。

答案 1 :(得分:1)

  

当我使用调试器时,地图的键是正确的但是在哪里   value应该是另一个map,它改为class std :: _ Tree&lt;&gt ;.能够   有人解释为什么会这样吗?

这暗示了编译器如何实现std::map

它看起来像是Visual C ++。如果您查看计算机上的标题文件(它应该类似于C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\map),那么您可能会看到std::map公开来自_Tree。它没有任何魔力;它只是简单的公开推导。

现在,名称_Tree已经表明它是一个实现细节。在您自己的代码中不允许使用这样的名称(下划线+大写字母),但编译器本身可以在其自己的头文件中自由使用它。这是因为就C ++语言而言,标准库头文件不存在。您可以完美地编写符合标准的C ++编译器,而不需要任何头文件,其中用户代码(如#include <map>)将在不读取任何文件的情况下进行解释。只是出于简单和实际的原因,我所知道的所有C ++编译器(以及可能存在的所有C ++编译器)都带有头文件文件

重点是编译器自己的头文件可能包含所有内容,包括非C ++代码,专有构造和客户端不需要注意的其他奇怪的东西,但编译器需要它们才能实现C ++标准库。

_Tree就是这样。查看标准头文件或使用调试器会向您展示它。

所有这些都非常好,只要你不试图在你自己的代码中摆弄它。例如,请使用以下 evil 代码:

#include <map>

int main()
{
    // Just for demonstration purposes!
    // Do not EVER try this in production code!

    using namespace std;
    _Tree<_Tmap_traits<int,
        int,
        less<int>,
        allocator<int>,
        false>
    > m{ less<int>(), allocator<int>() };
}

很可能编译和使用MSVC,但是使程序不可移植,甚至可能与同一编译器的未来版本或过去版本不兼容,因为您在自己的代码中使用了编译器内部组件。 / p>

简而言之:您自己的代码必须不知道_Tree存在的事实。

答案 2 :(得分:0)

正如您在评论中提到的,问题是如何从std::map访问以下示例:

#include<map>
#include<string>
#include<iostream>

int main()
{
    std::map<int,int> key = { {1,2}};
    std::map< std::map<int,int>,std::string> myMap;
    myMap[key]="hello";
    std::string val=  myMap[key];
    std::cout<<val;

}

修改

    std::map<int,int> key = { {1,2}};
    std::map< std::string, std::map<int,int>> myMap;
    myMap["hello"]=key;
    auto val=  myMap["hello"];
    for( const auto & p: val)
    std::cout<<p.first<<" "<<p.second;