c ++与呼叫不匹配

时间:2016-01-30 18:48:02

标签: c++ compiler-errors

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

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&amp ;, 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;   
}

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

您的代码存在两个问题,它们都出现在此行中:

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])明确说明。

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

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