首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >emplace(std::move(key),std::move(value)) vs emplace(std::make_pair(key,value))

emplace(std::move(key),std::move(value)) vs emplace(std::make_pair(key,value))
EN

Stack Overflow用户
提问于 2016-11-28 17:41:22
回答 2查看 1.6K关注 0票数 3

放置的两种方式:

代码语言:javascript
复制
std::unordered_map<std::string, std::string> m;

第一个:嵌入移动的关键点和值

代码语言:javascript
复制
// 1.
{
    std::string k1 = "key1";
    std::string v1 = "value1";
    m.emplace(std::move(k1), std::move(v1));
}

第二: emplace with pair made std::make_pair

代码语言:javascript
复制
// 2.
{
    std::string k2 = "key2";
    std::string v2 = "value2";
    m.emplace(std::make_pair(k2, v2));
}

哪个更好(意味着更快更高效)?

EN

回答 2

Stack Overflow用户

发布于 2016-11-28 18:03:49

哪个更好?

如何做得更好?它们不是等价的。

示例1调用k1v1的move构造函数,使它们处于有效但不同的状态,它们的内容将被移走。如果你打算在之后使用k1v1,那么没有选择,你应该使用#2。如果你不这样做,那么你也应该搬到#2,以避免复制:

代码语言:javascript
复制
m.emplace(std::make_pair(std::move(k2), std::move(v2)));

这就把它留给了可读性:

代码语言:javascript
复制
m.emplace(std::move(k1), std::move(k2));

这将调用std::pair的模板构造函数来从2个右值引用构造std::pair

代码语言:javascript
复制
m.emplace(std::make_pair(std::move(k2), std::move(v2)));

这调用了std::pair的move构造函数,因为它是一个右值。

如果是“哪个更好?”你的意思是性能,那么只有一种方法可以找到答案,那就是基准测试。虽然我认为m.emplace(std::move(k1), std::move(k2));有轻微的优势。(如注释中所述,因为它避免了从非常数到常量的转换)

要点,不用担心,它们都是非常有效的,因为它们都在移动。选择你认为可读性更好的那一个。

票数 2
EN

Stack Overflow用户

发布于 2016-11-28 18:25:28

第二种选择需要额外的移动/复制操作,这是不好的。第一个选项的运行速度更快,因为没有显式创建对。实际上,在显式创建std::pair的情况下插入和定位可以提供相同的速度。

我测试过了。带有std::make_pair的选项需要对键/值调用3次移动构造函数,带有std::move的选项只需要调用1次移动构造函数。不使用和使用/Ox优化的示例。msvc-2012

代码语言:javascript
复制
class C
{
    public:
    C()
    {
       std::cout << "C()" << std::endl;
    }

    C( const C& c )
    {
       std::cout << "copy" << std::endl;
    }

    C( C&& c )
    {
       std::cout << "move" << std::endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::unordered_map<int, C> c1;

    std::cout << "---Test Move---" << std::endl;
    C test1;
    c1.emplace(1, std::move(test1));

    std::cout << "---Test std::make_pair---" << std::endl;
    C test2;
    c1.emplace(std::make_pair(2, test2) );

    std::cout << "---Test bare pair---" << std::endl;
    C test3;
    c1.emplace(std::pair<const int, C>(3, test3) );

    return 0;
}

-测试移动--

C()

移动

-测试std::make_pair

C()

复制

移动

移动

-测试裸对

C()

复制

移动

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40841174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档