所以,我有以下代码:
#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
在这里:
现在很有趣:
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)......
现在我想知道哪一个是对的,更具体地说为什么?
答案 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。