访客除了说什么:
void emplace_back(Type&& _Val)
MSCV10提供的功能不符合标准且具有冗余性,因为正如您所指出的,它严格等同于push_back(Type&& _Val)
。
但真正的C ++ 0x形式emplace_back
是真正有用的:void emplace_back(Args&&...)
;
无需采用取而代之的value_type
是可变参数列表,因此,这意味着您现在可以完美地转发参数,并直接将对象构造到容器中,而无需任何临时操作。
这很有用,因为无论RVO和移动语义多么聪明,仍然存在复杂的情况,其中push_back可能会产生不必要的副本(或移动)。例如,使用a的传统insert()
功能std::map
,您必须创建一个临时,然后将其复制到a中std::pair<Key, Value>
,然后将其复制到地图中:
std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";
// cross your finger so that the optimizer is really good
m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
那么,为什么他们没有在MSVC中实现正确版本的emplace_back?实际上,它在一段时间之前困扰着我,因此我在Visual C ++博客上提出了同样的问题。这是Microsoft Visual C ++标准库实现的官方维护者Stephan T Lavavej的回答。
问:beta 2 emplace函数现在只是某种占位符吗?
答:您可能知道,可变参数模板未在VC10中实现。我们使用预处理器机器对它们进行仿真,以处理诸如
make_shared<T>()
,元组和中的新事物<functional>
。这种预处理器机器相对难以使用和维护。另外,由于我们不得不反复包含子标题,因此它会显着影响编译速度。由于时间限制和编译速度方面的考虑,我们没有在emplace函数中模拟可变参数模板。
当可变参数模板在编译器中实现时,您可以期望我们将在库中使用它们,包括在我们的emplace函数中。我们非常重视一致性,但不幸的是,我们不能一次完成所有事情。
这是一个可以理解的决定。每个曾经尝试使用预处理器可怕技巧来模拟可变参数模板的人都知道这些东西有多恶心。