【问题标题】:c++ no match for call toc++ 不匹配调用
【发布时间】:2016-05-08 10:27:08
【问题描述】:

我写了下面的代码,它给出了一个错误;

ipt.cpp:在函数‘bool isprimet(long unsigned int, int)’中: ipt.cpp:28:86: 错误: 不匹配调用 '(std::thread) (void (&)(long unsigned int, long unsigned int, long unsigned int, bool), const long unsigned int&, long unsigned int&, long unsigned int&, unsigned int&)' for (unsigned long c=0;c

我做错了什么?

#include <iostream>
#include <thread>
#include <math.h>

using namespace std;

void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
{
   result=true;   
   for (unsigned long c=5+threadid*6;c<=root;c+=(threadid+1)*6)
   {
      if(number % c-1 == 0) {result=false; break;};
      if(number % c+1 == 0) {result=false; break;};
   }
}

bool isprimet(const unsigned long number, const int nthreads)
{
   if (number > 1)
   {
      if (number > 3)
      {
         if (number % 2 == 0) return false;
         if (number % 3 == 0) return false;
     unsigned int results[nthreads];
     unsigned long root=(unsigned long)floor(sqrt(number))+1;
     thread t[nthreads];
     for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
     for (unsigned long c=0;c<nthreads;c++) t[c].join();
     for (unsigned long c=0;c<nthreads;c++) if (results[c]==false) return false;
     return true;   
     }
      else return true;
   }
   else return false;   
}

【问题讨论】:

    标签: c++ compiler-errors


    【解决方案1】:

    使用std::thread时,需要向std::thread的构造函数发送一个可调用对象,可以使用Lambda表达式:

    t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
    

    以下代码有效:

    #include <thread>
    #include <math.h>
    #include <iostream>
    
        using namespace std;
        static int const MAX_THREADS = 128;
    
        void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
        {
            result = true;
            for (unsigned long c = 5 + threadid * 6; c <= root; c += (threadid + 1) * 6)
            {
                if (number % c - 1 == 0) { result = false; break; };
                if (number % c + 1 == 0) { result = false; break; };
            }
        }
    
        bool isprimet(const unsigned long number, const unsigned long nthreads)
        {
            if (number > 1)
            {
                if (number > 3)
                {
                    if (number % 2 == 0) return false;
                    if (number % 3 == 0) return false;
                    bool results[MAX_THREADS];
                    unsigned long root = (unsigned long)floor(sqrt(number)) + 1;
                    thread* t[MAX_THREADS];
                    for (unsigned long c = 0; c < nthreads; c++)
                        t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
                    for (unsigned long c = 0; c < nthreads; c++) {
                        t[c]->join();
                        delete t[c];
                    }
                    for (unsigned long c = 0; c < nthreads; c++) 
                        if (results[c] == false) 
                            return false;
                    return true;
                }
                else return true;
            }
            else return false;
        }
    
    int main(int argc, char *argv[])
    {
        for (int i = 1; i < 100; ++i)
            if (isprimet(i,5))
                cout << i << "\n";
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      您的代码有两个问题,它们都出现在这一行:

      for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
      

      应该是这样的:

      for (unsigned long c=0;c<nthreads;c++) t[c] = std::thread(ipt, number, root, c, std::ref(results[c]));
      

      第一个问题是你调用函数的方式——你可以使用上面显示的赋值运算符。

      其次,将参数传递给线程的默认方式是按值传递。但是,您的函数原型指定您希望通过引用传递results[c],因此您需要明确声明使用std::ref(results[c])

      此外,您使用非常量变量设置静态数组的大小(因此编译器在编译时不知道大小),因此所有编译器警告。您需要使用一个常量来设置大小,或者定义一个全局常量并使用它,或者将线程数作为模板参数传递,这将消除编译器警告。

      这是一个没有警告的工作示例的live demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 2019-04-09
        相关资源
        最近更新 更多