错误代码:C2661:没有重载函数需要6个参数

时间:2018-08-13 14:35:50

标签: c++ visual-studio-2015

此程序的确从队列中获取文件名,在用户输入文件名后,该文件名即为 myQue ,然后将其放入 mainQue 中,然后打开这些文件并将其解密。如果可能的话。如果解密成功,则它将解密后的数据写入新文件。

Main.cpp

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "Queue.h"
#include "randgen.h"
#include <thread>
#include <mutex>

using namespace std;

Queue myQue;        //My structure to store the file names
Queue mainQue;      //Main que for the threads
RandGen Ran;        //Random Generator object

// Mutexes for certain restrictions
std::mutex mtx_blockMyQue, mtx_blockMainQue, mtx_blockPrint;

//Function for decrypt the message
void decipher(string str, int shift) 
{
    for (int i = 0; i < str.length(); ++i) 
    {
        if (str[i] >= 'a' && str[i] <= 'z') 
        {
            str[i] = str[i] + shift;
        }
    }
}

//Function for finding the most frequent letter
char mostFrequent(string text)
{
    int max = 0;
    int count = 0;
    char maxCharcter;
    for (char q = 'a'; q <= 'z'; q++)
    {
        count = 0;
        for (int i = 0; i<text.length(); i++)
        {
            if (text[i] == q)
                count++;
        }
        if (count>max)
        {
            max = count;
            maxCharcter = q;
        }
    }
    return maxCharcter;
}

void sleepThr(int thrNum, int time)
{
    mtx_blockPrint.lock();
    this_thread::sleep_for(chrono::milliseconds(time));
    cout << "Producer Thread - " << thrNum << " starts sleeping for " << time << "milliseconds" << endl;
    mtx_blockPrint.unlock();
}

//What producer threads do
void producer(Queue &myQue, Queue &mainQue , int thrNum, int time,string &input)
{
    this_thread::sleep_for(chrono::milliseconds(time));   //Sleep thread
    cout << "Producer Thread - " << thrNum << " starts sleeping for " << time << "milliseconds" << endl;

    //sleepThr(thrNum, time);

    mtx_blockMyQue.lock();      //Thread locked

        if (myQue.isEmpty()==false) 
        {
            cout << "Producer Thread - " << thrNum << " is now enqueuing '" << input << "'" << endl;
            //Value to be dequeued and then to be enqueued
                                    //Dequeueing the value
            mainQue.enqueue(input); //Enqueueing the value
        }
        mtx_blockMyQue.unlock();        //Thread unlocked

        //mtx_blockPrint.lock();        //Thread locked
        this_thread::sleep_for(chrono::milliseconds(time));   //Sleep thread
        cout << "Producer Thread - " << thrNum << " starts sleeping for " << time << "milliseconds" << endl;
        //mtx_blockPrint.unlock();  //Thread unlocked


}

//What consumer threads do
void consumer(Queue &mainQue, int thrNum , int time , string &input, fstream &reader)
{
    //this_thread::sleep_for(chrono::milliseconds(time));   //Sleep thread
    //cout << "Consumer Thread - " << thrNum << " starts sleeping for " << time << "milliseconds" << endl;
    mtx_blockPrint.lock();      //Thread locked

    this_thread::sleep_for(chrono::milliseconds(time));   //Sleep thread
    cout << "Consumer Thread - " << thrNum << " starts sleeping for " << time << "milliseconds" << endl;

    mtx_blockPrint.unlock();    //Thread unlocked

    mtx_blockMainQue.lock();

    cout << "Consumer Thread - " << thrNum << " is now handling '" << input << "'" <<endl;
    string line;
    reader.open(input);
    if (!reader.is_open()) 
    {
        cout << "Consumer Thread - " << thrNum << " cannot process '" << input << "', there is no such file!" << endl;
    }
    else 
    {
        getline(reader, line, '.');                         //Read file ignoring '.'
        char mostChr = mostFrequent(line);                  //The most frequent char
        char e = 'e';                                       
        int intChr = mostChr;                               //Decimal of the most frequent char
        int intE = e;                                       //Decimal of the char 'e'
        int shiftNum = intChr - intE;                       //Shift number
        decipher(line, shiftNum);                           //Decrypting the message
        string outputFile = input + "_decrypted.txt";
        ofstream output(outputFile);                        //Opening a new output file for decrypted message
        output << line;                                     //Putting the decrypted message into the file
        output.close();                                     //Closing the output file
        cout << "Consumer Thread - " << thrNum << " is done handling " << input << " with a shift of " << shiftNum << " and written the result to '" << outputFile << "'" << endl;
    }
    reader.close();

    mtx_blockMainQue.unlock();
}

int main() {

    fstream reader;             //Reader
    string inputFileName;       //File name
    int time1[2], time2[3];

    cout << "Enter a file name: ";
    cin >> inputFileName;
    myQue.enqueue(inputFileName);   //Storing the file name in my structure

    //Do this task until the dash(-) character entered
    while(inputFileName != "-")
    {
        cout <<  "Enter a file name: ";
        cin >> inputFileName;
        myQue.enqueue(inputFileName);
    }
    thread prodThr[2];  //Constructing Producer Threads
    thread consThr[3];  //Constructing Consumer Threads
/*
    for (int i = 0; i < 1; i++) {

        time1[i] = Ran.RandInt(1000, 4000);
        prodThr[i] = thread(&sleepThr, i + 1, time1[i]);
    }
    for (int i = 0; i < 2; i++)
    {
        time2[i] = Ran.RandInt(2500, 3500);
        consThr[i] = thread(&sleepThr, i + 1, time2[i]);
    }
    */
    while (myQue.isEmpty() == false) 
    {

        for (int i = 0; i<2; i++) {

            time1[i] = Ran.RandInt(1000, 4000);
            myQue.dequeue(inputFileName);
            prodThr[i] = thread(&producer, myQue, mainQue, i + 1, time1[i], inputFileName);
        }

        for (int i = 0; i<3; i++) {
            time2[i] = Ran.RandInt(2500, 3500);
            if (mainQue.isEmpty() == false) 
            {
                mainQue.dequeue(inputFileName);
                consThr[i] = thread(&consumer, mainQue, i + 1, time2[i], inputFileName, reader);
            }
        }
        //Joining Producer Threads
        for (int i = 0; i < 2; i++) {
            prodThr[i].join();
        }
        //Joining Consumer Threads
        for (int i = 0; i<3; i++) {
            consThr[i].join();
        }
    }

    return 0;
}

Queue.cpp

#include <iostream>
#include "Queue.h"
using namespace std;

//************************************************
// Constructor. Generates an empty queue         *
//************************************************
Queue::Queue()
{
    front = nullptr;
    rear = nullptr;
}

//********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue.                 *
//********************************************
void Queue::enqueue(string val)
{       
    if (isEmpty())   //if the queue is empty
    {   //make it the first element
        front = new QueueNode(val);
        rear = front;
    }
    else  //if the queue is not empty
    {   //add it after rear
        rear->next = new QueueNode(val);
        rear = rear->next;
    } 
}

//**********************************************
// Function dequeue removes the value at the   *
// front of the queue, and copies it into num. *
//**********************************************
void Queue::dequeue(string &val)
{
    QueueNode *temp;
    if (isEmpty())
    {
        exit(1);
    }
    else //if the queue is not empty
    {   //return front's value, advance front and delete old front
        val = front->value;
        temp = front;
        front = front->next;
        delete temp;      
    }
}

//*********************************************
// Function isEmpty returns true if the queue *
// is empty, and false otherwise.             *
//*********************************************
bool Queue::isEmpty() const
{
    if (front == nullptr)
        return true;
    else 
        return false;
}

//********************************************
// Function clear dequeues all the elements  *
// in the queue.                             *
//********************************************
void Queue::clear()
{
    string val;   // Dummy variable for dequeue

    while(!isEmpty())
        dequeue(val); //delete all elements
}

Queue.h

#ifndef DYNINTQUEUE_H
#define DYNINTQUEUE_H
#include <string>
using namespace std;

struct QueueNode
{
    string value;
    QueueNode *next;
    QueueNode(string val, QueueNode *ptr = nullptr)
    {
        value = val;
        next = ptr;
    }

};

class Queue
{
    private:
        // These track the front and rear of the queue.
        QueueNode *front;
        QueueNode *rear;    
    public:
        // Constructor.
        Queue();

        // Member functions.
        void enqueue(string);
        void dequeue(string &);
        bool isEmpty() const;     
        void clear();
};
#endif

randgen.cpp

#include <time.h>                // for time()
#include <stdlib.h>              // for rand/srand
#include "randgen.h"
#include <cmath>

#include <iostream>
using namespace std;

int RandGen::ourInitialized = 0;

void RandGen::SetSeed(int seed)
// postcondition: system srand() used to initialize seed
//                once per program (this is a static function)    
{
    if (0 == ourInitialized)
    {   ourInitialized = 1;   // only call srand once
    srand(seed);          // randomize
    }
}


RandGen::RandGen()
// postcondition: system srand() used to initialize seed
//                once per program     
{
    if (0 == ourInitialized)
    {   ourInitialized = 1;          // only call srand once


        time_t now;
        time (&now); // localtime bir zamandan itibaren geçen saniye formatında
                     // now değişkenine kaydedilir.
        srand(int((sin(double(now))*1000000)));//Gökhan
        // seed'imiz her saniye bir artmasın diye
                                        // daha random artsın diye sinusunu alıyorum 
 //       srand(unsigned(time(0)));    // randomize
    }
}

int RandGen::RandInt(int max)
// precondition: max > 0
// postcondition: returns int in [0..max)     
{  
    return int(RandReal() * max);
}

int RandGen::RandInt(int low, int max)
// precondition: low <= max     
// postcondition: returns int in [low..max]     
{ 
    return low + RandInt(max-low+1);
}

double RandGen::RandReal()
// postcondition: returns double in [0..1)     
{     
    return rand() / (double(RAND_MAX) + 1); 
}

double RandGen::RandReal(double low, double high)
{
    double width = fabs(high-low);
    double thelow = low < high ? low : high;
    return RandReal()*width + thelow;
}

randgen.h

#ifndef _RANDGEN_H
#define _RANDGEN_H

#include <limits.h>                     // for INT_MAX

// designed for implementation-independent randomization
// if all system-dependent calls included in this class, then
// other classes can make use of this class in independent manner
// all random numbers are uniformly distributed in given range
//
// RandGen() ---      constructor sets seed of random # generator
//                    once per program, not per class/object
//     
// RandInt(int max)
// RandInt(int low,int max) - return random integer in range [0..max)
//                     when one parameter used, [low..max] when
//                     two parameters used
//
//       examples:    rnd.RandInt(6) is random integer [0..5] or [0..6)
//                    rnd.RandInt(3,10) is random integer [3..10]
//                    rnd.RandInt()  is random integer [0..INT_MAX)
//
// RandReal()       -- returns random double in range [0..1)
// RandReal(double low, double max) -- random double in range [low..max)

class RandGen
{
  public:
    RandGen();                          // set seed for all instances
    int RandInt(int max = INT_MAX);     // returns int in [0..max)
    int RandInt(int low, int max);      // returns int in [low..max]
    double RandReal();                  // returns double in [0..1)
    double RandReal(double low, double max); // range [low..max]

    static void SetSeed(int seed);      // static (per class) seed set
private:
    static int ourInitialized;          // for 'per-class' initialization
};

#endif

我已经检查了所有内容,但是我不明白为什么编译器会给我这个错误。我正在使用Microsoft Visual Studio 2015。

1 个答案:

答案 0 :(得分:2)

了解thread构造函数(here)和reference_wrapper

  

线程函数的参数按值移动或复制。如果需要将引用参数传递给线程函数,则必须将其包装(例如,使用std :: ref或std :: cref)。

您的功能签名是

void producer(Queue &myQue, Queue &mainQue , int thrNum, int time,string &input)

因此您必须将 thread 构造函数的调用更改为

prodThr[i] = thread(&producer, std::ref(myQue), std::ref(mainQue), 
   i + 1, time1[i], std::ref(inputFileName));

consumer函数执行相同操作。