std::thread 只允许一个参数[关闭]

Posted

技术标签:

【中文标题】std::thread 只允许一个参数[关闭]【英文标题】:std::thread only allows one argument [closed] 【发布时间】:2021-04-04 02:59:00 【问题描述】:

我正在尝试在 C++ 中使用 std::thread。我的问题是它只允许 1 个参数(目标函数)。这意味着我不能将参数传递给线程。我不知道为什么。这是我的代码。

#include <thread>
#include <iostream>

void run_thread(int num) 
    std::cout << num << std::endl;


int main() 
    std::thread t(run_thread, 5);
    return 0;

这是错误信息。

test.cpp:9:17: error: no matching constructor for initialization of 'std::thread'
    std::thread t(run_thread, 5);
                ^ ~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:340:9: note: 
      candidate constructor template not viable: requires single argument '__f', but 2
      arguments were provided
thread::thread(_Fp __f)
        ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:220:5: note: 
      candidate constructor not viable: requires 1 argument, but 2 were provided
    thread(const thread&);
    ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:227:5: note: 
      candidate constructor not viable: requires 0 arguments, but 2 were provided
    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) 
    ^
1 error generated.

我运行g++ -o test test.cpp 来编译它。 我在 Apple 设备上。 这是gcc -v的输出

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.21)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

谁能告诉我这是怎么回事?

【问题讨论】:

Can't reproduce 也投票结束,因为这个问题是基于一个不正确的断言。 en.cppreference.com/w/cpp/thread/thread/thread构造函数需要额外的参数 【参考方案1】:

它只允许 1 个参数(目标函数) - 这似乎是错误的.. 它可以允许更多,有关更多信息,请查看 cppreference 函数的参数是可变的不固定

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

试试这个

如果尚未编译,请确保使用 -std=c++11 编译

#include <iostream>
#include <utility>
#include <thread>
#include <chrono> 
 
void f1(int n, int n2)

    for (int i = 0; i < 5; ++i) 
        std::cout << "Thread  executing "  << n2 << "\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    


void f2(int n, int n2, int n3)

    for (int i = 0; i < 5; ++i) 
        std::cout << "Thread  executing "  << n2  << " " << n3 << "\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    

int main()

    int x = 5, extra = 7, extra2 = 9;
    std::thread t1(f1, x, extra);
    t1.join();
    std::thread t2(f2, x, extra, extra2);
    t2.join();
    return 0;

【讨论】:

【参考方案2】:

在这种情况下,您可以使用 lambda:

std::thread t( []()  run_thread(5);  );

投诉没用后,我写了这个:

#include <iostream>
#include <thread>

using namespace std;

void someMethod(int value) 
    cout << "someMethod(" << value << ")" << endl;


int main(int, char **) 
    thread t([]()  someMethod(5); );
    t.join();
    cout << "Done." << endl;

然后我这样做了:

g++ -std=c++17 Foo.cpp -o Foo && Foo

someMethod(5)
Done.

我不知道什么不起作用。

【讨论】:

没用test.cpp:9:20: error: expected expression std::thread t( []() run_thread(5); ); @DylanRiley:显式传递一个标志以选择加入 C++11 或更高版本;我猜你得到的是 C++11 头文件,在 C++11 之前的模式下编译,事情进展得非常非常糟糕。 否决了强调另一个答案,这表明问题不正确,您可以将参数传递给 std::thread。在这种情况下,接受的答案在技术上是正确的,但不是最佳答案。 @xaxxon 合理。已经很晚了,我现在一直在使用 lambda 模式,因为我的方法总是非静态类方法。 std::bind 也可以,但我讨厌这种语法。我什至没有想过要质疑这个问题本身是否有缺陷。

以上是关于std::thread 只允许一个参数[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥构造 std::thread 时参数移动了两次

std::unique_ptr 作为参数在 std::thread 中起作用 [重复]

std::thread创建线程,使用std::ref()传递类对象参数

std::thread创建线程,使用std::ref()传递类对象参数

std::thread创建线程,使用std::ref()传递类对象参数

std::thread 中的参数。如何运作?