3
#include <iostream>
#include <map>
using namespace std;

struct FooStruct 
{
    int a;
    int b;
};

int main()
{
    map<int, FooStruct> fooMap;
    fooMap.emplace<int, FooStruct>(0, {1, 2});
    return 0;
}

在防止临时复制方面,以上是emplace的正确用法吗?上述形式是否优于

fooMap.emplace(make_pair<int, FooStruct>(0, {1, 2}));

或者这些形式是否等效并且它们都避免创建FooStruct?

4

2 回答 2

1

如果您将“正确性”定义为简洁,您可能希望使用std::map::insert而不是std::map::emplace这样:

fooMap.insert({0, {1, 2}});

在@max66 建议的情况下emplace,您必须像在示例中那样显式指定类型,或者显式定义构造函数:FooStruct

fooMap.emplace(std::piecewise_construct,
    std::forward_as_tuple(0),
    std::forward_as_tuple(1, 2));

(这也缺乏简洁性)。

fooMap.insert({0, {1, 2}});不应该不同于

fooMap.emplace(make_pair<int, FooStruct>(0, {1, 2}));

就创建的对象数量而言,它还使用std::pair@Swift 指出的 move-constructor 。

如果“正确”意味着“可编译并在运行时按预期工作”,那么您的两个示例都是正确的。

于 2017-08-05T09:41:44.313 回答
0

编辑:

在这个线程中讨论的三种形式中,避免不必要复制的一种是@max66 提出的形式。以下代码及其输出捕获了这三种形式的实际操作

#include <iostream>
#include <map>
using namespace std;

struct FooStruct 
{
    FooStruct() 
    { 
        cout << "FooStruct Default Constructor" << endl; 
    }
    FooStruct(const FooStruct& other) 
    {
        this->a = other.a;
        this->b = other.b;
        cout << "FooStruct Copy Constructor" << endl;
    }
    FooStruct(int a, int b)
    {
        this->a = a;
        this->b = b;
        cout << "FooStruct Parametrized Constructor" << endl;
    }
    int a;
    int b;
};

输出:

foo.emplace<int, FooStruct>(0, {1, 2})
FooStruct Parametrized Constructor
FooStruct Copy Constructor
fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }))
FooStruct Parametrized Constructor
FooStruct Copy Constructor
FooStruct Copy Constructor
fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4))
FooStruct Parametrized Constructor

=============

原件(错误)

我有点懒惰,在发布问题之前没有尝试深入挖掘。我现在看到所有这三种形式(第三种形式来自@max66 的评论)都是等价的,因为它们都避免创建FooStruct.

#include <iostream>
#include <map>
using namespace std;

struct FooStruct 
{
    FooStruct() { cout << "FooStruct Default Constructor" << endl; }
    FooStruct(int a, int b) { this->a = a; this->b = b; cout << "FooStruct Parametrized Constructor" << endl; }
    int a;
    int b;
};

int main()
{
    map<int, FooStruct> fooMap;
    fooMap.emplace<int, FooStruct>(0, {1, 2});
    fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }));
    fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4));
    return 0;
}

上述代码(使用 Visual C++ 2015 构建)产生以下输出:

FooStruct Parametrized Constructor
FooStruct Parametrized Constructor
FooStruct Parametrized Constructor

PS:我确实验证了上述输出中的每一行都对应于上面的单个 emplace 调用

于 2017-08-04T01:51:38.637 回答