繁体   English   中英

线程构造函数初始化 C++

[英]Thread Constructor Initialization C++

我一直在尝试编写一个简单的程序来试验线程向量。 我目前正在尝试创建一个线程,但我发现我遇到了一个错误,即我的构造函数没有正确初始化,错误是没有匹配参数列表的 std::thread 构造函数。 这是我所做的:

#include <functional>
#include <iostream>
#include <numeric>
#include <thread>
#include <vector>

int sum = 0; 
void thread_sum (auto it, auto it2, auto init) {
  sum = std::accumulate(it, it2, init);
}

int main() {
  // * Non Multi-Threaded
  // We're going to sum up a bunch of numbers.
  std::vector<int> toBeSummed;
  for (int i = 0; i < 30000; ++i) {
    toBeSummed.push_back(1);
  }
  // Initialize a sum variable
  long sum = std::accumulate(toBeSummed.begin(), toBeSummed.end(), 0);

  std::cout << "The sum was " << sum << std::endl; 
  // * Multi Threaded
  // Create threads
  std::vector<std::thread> threads;
  std::thread t1(&thread_sum, toBeSummed.begin(), toBeSummed.end(), 0);
  std::thread t2(&thread_sum, toBeSummed.begin(), toBeSummed.end(), 0);
  threads.push_back(std::move(t1));
  threads.push_back(std::move(t2));
  return 0; 
}

搞砸的行如下:

  auto t1 =
      std::thread {std::accumulate, std::ref(toBeSummed.begin()), 

这是构造函数的问题。 I have tried different combinations of std::ref, std::function, and other wrappers, and tried making my own function lambda object as a wrapper for accumulate.

以下是一些附加信息:

错误消息是:atomics.cpp:28:7: 错误:没有匹配的构造函数用于初始化 'std::thread'

此外,当悬停在构造函数上时,它告诉我第一个参数是 <unknown_type>。

我尝试过的其他尝试:

  • 使用引用而不是常规值参数
  • 使用std::bind
  • 使用std::function
  • 在变量中声明 function 并将其作为我的第一个参数传递给构造函数
  • 使用不同的标志编译,例如std=c++2a

编辑

  1. 我会留下最初的问题,作为其他人从我的错误中吸取教训的一种手段。 正如我接受的答案将显示的那样,这是由于我过度使用 auto。 我读过一本 C++ 书,它基本上说“总是使用自动,它的可读性更高,就像 Python 和动态类型,但具有 ZF6F87C9FDCF8B3C3F07F93F1EE8712CZ9 的性能。” 但很明显,这并不总是可以做到的。 using关键字提供了可读性,同时仍然安全。 谢谢你的回答!

您遇到的问题是因为std::accumulate是一个重载的 function 模板,所以编译器不知道什么特定的 function 类型将其视为作为参数传递给线程构造函数时。 由于auto参数,您的thread_sum function 也会出现类似问题。

您可以选择std::accumulate的特定重载/实例化,如下所示:

  std::thread t2(
      (int(*)(decltype(toBeSummed.begin()), decltype(toBeSummed.end()), int))std::accumulate,
       toBeSummed.begin(), toBeSummed.end(), 0);

问题是您过度使用auto 您可以通过更改这一行来修复它:

void thread_sum (auto it, auto it2, auto init) {

对此:

using Iter = std::vector<int>::const_iterator;
void thread_sum (Iter it, Iter it2, int init) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM