You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何std::vector<std::jthread>无法通过std::initializer_list初始化?

std::vectorstd::jthread列表初始化报错的问题分析

代码示例

可正常运行的代码

#include <thread>
#include <vector>
#include <iostream>

int main() {
    std::vector<std::jthread> threads;
    
    threads.emplace_back([] {
        std::cout << "New thread via .emplace_back()" << std::endl;
    });
}

编译报错的代码

#include <thread>
#include <vector>
#include <iostream>

int main() {
    std::vector<std::jthread> threads {
        {[] {
            std::cout << "New thread during initialization" << std::endl;
        }}
    };
}

编译错误信息:

error: use of deleted function 'std::jthread::jthread(const std::jthread&)'

核心疑问

  • 是否存在未定义行为?根据std::vector构造函数#5的说明,可能是元素不满足EmplaceConstructible,但为何第一段代码无报错?
  • 是否与constexpr相关?
  • 为何会调用拷贝构造函数?这种初始化方式的初衷不就是避免不必要的拷贝构造吗?

问题原因解析

1. 列表初始化触发的构造路径问题

当使用std::vector<T> obj { {...} }的列表初始化语法时,编译器会优先匹配vector的初始化列表构造函数(C++标准中的构造函数#7),而非你预期的emplace构造(构造函数#5)。这个构造函数的执行逻辑是:

  1. 先将初始化列表中的每个元素构造为T的临时对象;
  2. 再尝试将这些临时对象拷贝或移动到vector的内存空间中。

由于std::jthread是不可拷贝的资源类,其拷贝构造函数被显式删除。而初始化列表中的临时对象会被视为const T类型,移动构造需要非const的右值引用,编译器无法调用移动构造,只能尝试调用已删除的拷贝构造,最终触发报错。

2. emplace_back正常运行的原因

emplace_back的核心逻辑是在vector已分配的内存空间中原地构造元素:它会直接把你传入的参数(这里是lambda表达式)转发给std::jthread的构造函数,全程不会产生临时对象,自然也不会涉及拷贝或移动操作,因此可以正常构造不可拷贝的jthread对象。

3. 关于EmplaceConstructible和constexpr的疑问解答

  • 不存在未定义行为,问题完全源于构造函数的匹配逻辑差异。第一段代码用emplace_back原地构造,满足EmplaceConstructible要求;第二段走初始化列表构造路径,和EmplaceConstructible无关。
  • 与constexpr无关,std::jthread的构造函数并非constexpr,但这不是报错的触发点,核心还是构造路径导致的拷贝构造调用。

可行的解决方式

如果想在vector初始化阶段直接构造jthread,可以采用以下两种方式:

  • 利用C++20引入的std::from_range构造,直接原地构造元素:
#include <thread>
#include <vector>
#include <iostream>
#include <functional>
#include <ranges>

int main() {
    std::vector<std::jthread> threads(std::from_range, std::initializer_list<std::function<void()>>{
        [] { std::cout << "New thread during initialization" << std::endl; }
    });
}
  • 保持默认构造vector,再通过emplace_back逐个添加元素(即第一段代码的实现方式)。

内容的提问来源于stack exchange,提问作者ocebe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:42:50