g ++ 4.9.2和rvalue参考图

时间:2015-06-19 11:02:12

标签: c++11 rvalue-reference

所以,我有以下代码:

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

struct MockMapItem {
    std::string property;

    MockMapItem(const std::string& value) : property(value) {
        std::cout << "constructed MockMapItem with a string!" << std::endl;

    }
};

typedef typename std::map<std::string, const MockMapItem&& > ItemMap;

int main()
{
    MockMapItem map_item("some string value");

    ItemMap themap;
    themap.emplace("something", std::move(map_item));

}

为方便访问,我把它放在这里:

http://coliru.stacked-crooked.com/a/7e80bc37d904510d

在这里:

http://ideone.com/2wkOmC

现在很有趣:

coliru网站编译并运行它。

构思之一会出现以下错误:

Compilation error   time: 0 memory: 0 signal:0

prog.cpp:14:60: error: template argument 2 is invalid
 typedef typename std::map<std::string, const MockMapItem&& > ItemMap;
                                                        ^
prog.cpp:14:60: error: template argument 4 is invalid
prog.cpp:14:62: error: 'ItemMap' in namespace 'std' does not name a type
 typedef typename std::map<std::string, const MockMapItem&& > ItemMap;

但是我可以编译代码,尽管使用g ++ 4.8.4(和clang 3.4)......

现在我想知道哪一个是对的,更具体地说为什么

1 个答案:

答案 0 :(得分:2)

23.2.1表示容器的value_type必须可以从容器中删除,而23.2.4表示对于地图和多地图,这些要求适用于key_type和{{1 }}

引用类型不能从容器中删除,因为你不能形成指向引用类型的指针而不能使用mapped_type来销毁它(因为allocators只支持非const对象类型,而引用类型不是对象类型)。

因此allocator_traits::destroy类型无法满足容器中使用的要求,因此具有未定义的行为。

编辑:实际上在C ++ 11中,23.2.1中的要求只是const MockMapItem&&是可破坏的,而引用类型可破坏的。所以也许这在C ++ 11中是很好的,但不是C ++ 14。 HMM。