[c++]push_back的tip

在学习C++11线程std::thread的过程有这样一个场景。

#include <vector>
#include <thread>

void func() {}

int main()
{
    std::vector<std::thread> threadlist;
    std::thread trd{ func };
    threadlist.push_back(std::move(trd));

    return 0;
}

因为 std::thread 的实现中是删除了拷贝构造函数的,所有在调用 push_back 时需要传入一个右值,传入左值就会提示你拷贝构造已经被删除。

class thread {
    ...
public:
    ...

    thread(const thread&)            = delete;
    thread& operator=(const thread&) = delete;

    ...
};

但是,在查看 vector 的代码时,发现 push_back 有两个重载函数,传入常量左值引用也不会导致拷贝发生,那么这个拷贝构造是发生在什么地方呢?

_CONSTEXPR20 void push_back(const _Ty& _Val) { 
    // insert element at end, provide strong guarantee
    _Emplace_one_at_back(_Val);
}

_CONSTEXPR20 void push_back(_Ty&& _Val) {
    // insert by moving into element at end, provide strong guarantee
    _Emplace_one_at_back(_STD move(_Val));
}

在进行单步调式后,在一个 <xutility> 中找到了 construct_at 函数。

constexpr _Ty* construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(
    noexcept(::new(static_cast<void*>(_Location)) _Ty(_STD forward<_Types>(_Args)...))) /* strengthened */ {
    _MSVC_CONSTEXPR return ::new (static_cast<void*>(_Location)) _Ty(_STD forward<_Types>(_Args)...);
}

在 return 的时候使用 placement new 指定内存生成。其中_Ty(_STD forward<_Types>(_Args)...)就调用了拷贝构造函数。

所以,如果你的结构体或类删除了拷贝构造函数,就需要给 push_back 传入一个右值。当然,你也可以直接使用 emplace_back,也不会有这样的问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值