c++ multithreading class methods - c++

I have following problem.
vector<thread> vThreads;
list<Crob *> lRobs;
list<Crob *>::iterator i;
for(i = lRobs.begin(); i != lRobs.end(); i++)
{
vThreads.push_back(thread((*i)->findPath));
}
I want to pass the method findPath to a thread, but I just get a lot of errors...
> labrob.cpp: In function ‘int main(int, char**)’:
labrob.cpp:72:43: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>)’
labrob.cpp:72:43: note: candidates are:
In file included from labrob.cpp:14:0:
/usr/include/c++/4.7/thread:131:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int (Crob::*)(); _Args = {}]
/usr/include/c++/4.7/thread:131:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘int (Crob::*&&)()’
/usr/include/c++/4.7/thread:126:5: note: std::thread::thread(std::thread&&)
/usr/include/c++/4.7/thread:126:5: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘std::thread&&’
/usr/include/c++/4.7/thread:122:5: note: std::thread::thread()
/usr/include/c++/4.7/thread:122:5: note: candidate expects 0 arguments, 1 provided
make: *** [labrob.o] Error 1
I have already tried to pass local functions and that worked without problems...
Added CRob header
#pragma once
#include "point.hpp"
#include "lab.hpp"
class Crob
{
protected:
Cpoint *pos;
int steps;
Clab *labfind;
string direction;
public:
Crob(Clab *lab);
virtual ~Crob();
virtual void findPath();
void moveTo(int x, int y);
void moveToPrint(int x, int y);
int getSteps(void);
void checkDirection();
};

Looks like you're trying to pass a non-static method to the std::thread constructor. You cannot do that: a non-static methods needs a object so it can be called. Looks like you want:
for(i = lRobs.begin(); i != lRobs.end(); i++)
{
vThreads.push_back(std::thread(&Crob::findPath, *i));
}

Related

"error: attempt to use a deleted function" when attempting multithreading in C++

I have a program that is compute intensive that I would like to multithread. Here is the code:
#include <iostream>
#include <math.h>
#include <thread>
#include "print_binary.h"
#include "bit_at.h"
bool process(unsigned int start, unsigned int end) {
for (unsigned int i = 0; i < (sizeof(unsigned int)*8); i++)
{
for (unsigned int j = start; j < end; j++)
{
bit_at(i, j);
}
}
return true;
}
int main() {
unsigned int start {5000};
unsigned int end {11000};
std::thread thread_1 (process(start, end));
thread_1.join();
return 0;
}
When I attempt to compile this using g++20 on my M1 Mac, I get this error:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/thread:286:5: error: attempt to use a deleted function
_VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__config:856:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_ABI_NAMESPACE
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/thread:297:12: note: in instantiation of function template specialization 'std::__thread_execute<std::unique_ptr<std::__thread_struct>, bool>' requested here
_VSTD::__thread_execute(*__p.get(), _Index());
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/thread:313:54: note: in instantiation of function template specialization 'std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct>, bool>>' requested here
int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
^
and_threaded.cpp:23:17: note: in instantiation of function template specialization 'std::thread::thread<bool, void>' requested here
std::thread thread_1 (process(start, end));
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/type_traits:1916:5: note: '~__nat' has been explicitly marked deleted here
~__nat() = delete;
^
1 error generated.
Could someone explain to me what exactly error: attempt to use a deleted function means? My understanding is that std::thread converts the arguments passed to the function as rvalues, but the process() function should accept that. I have tried passing rvalues to process() like: std::thread thread_1(process(0, 5000)), as well as using rvalue references in the argument list of the function declaration. It all gives me the same error. I have also tried passing by reference using std::ref(start).
Any help at all is greatly appreciated.
process(start, end) calls the function process. And you pass the bool result to the std::thread constructor as a thread function.
You want to pass a pointer to the function itself, and its arguments, as separate arguments to the std::thread constructor:
std::thread thread_1 (&process, start, end);

Problems on throwing an object as an Exception: Keeping the same Constructor of parent Exception class

As my first C++ program I decided to make a simple TCP server based on previous knowledge from C and utilizing POSIX socket API:
Therefore, I made the following header file network.h:
#ifndef HTTP_NETWORK
#define HTTP_NETWORK
#include<string>
#include <arpa/inet.h>
//Dummy Value to be changed
#define MAXPENDING 5
class Exception {
public:
Exception(std::string message):message(message){}
std::string getMessage();
private:
std::string message;
};
class NetworkException:public Exception {};
class TCPServer{
public:
TCPServer(int port,std::string address);
~TCPServer();
void listen();
private:
int port;
//Socket file Descriptor
int servSock;
struct sockaddr_in ServAddr;
};
#endif
And afterwards I made and the network.cpp:
#include"network.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include<iostream>
#include<cstring>
#include<string>
std::string Exception::getMessage(){
return this->message;
}
TCPServer::TCPServer(int port,std::string address)
:port(port){
if ((this->servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
throw NetworkException(std::string("SOCKET Error: could not create basic socket"));
}
memset(&this->ServAddr,0,sizeof(this->ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(address.c_str());
ServAddr.sin_port = htons(port);
if (bind(this->servSock, (struct sockaddr *) &this->ServAddr, sizeof(this->ServAddr)) < 0) {
throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
}
if (::listen(this->servSock, MAXPENDING) < 0) {
throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
}
}
void TCPServer::listen(){
struct sockaddr_in ClntAddr; /* Client address */
socklen_t clntLen= (socklen_t)sizeof(ClntAddr);
int clntSock; /* Socket descriptor for client */
//#todo Dummy Logic Depedency Inject Socket Handler
for (;;) {
if ((clntSock = accept(servSock, (struct sockaddr *) &ClntAddr, &clntLen)) < 0) {
std::cout<<"Failed to fetch"<<std::endl;
}
send(clntSock, "12345\n", 6, 0);
std::cout << "Handling client %s\n" << inet_ntoa(ClntAddr.sin_addr) << std::endl;
close(clntSock);
}
}
TCPServer::~TCPServer(){
close(this->servSock);
}
But somehow I have hard time to throw an object as an exception:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:31:84: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:35:77: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
By first issue is that I have hard time to extend the Exception Class into something more Specific. Usually in other languages a generic class has been provided and I could be able to throw it as an exception. In C++ AFAIK any type can be thrownas an error hence I decided to have a class to be thrown.
But for now the plan backfires and I find myself hard to thow an anonymous Object of NetworkException I also tried to mitigate the issue by changing the NetworkException via:
class NetworkException:public Exception {
public:
NetworkException(std::string message){}
};
And still get errors:
In file included from ./src/main.cpp:4:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
NetworkException(std::string message){}
^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
Exception(std::string message):message(message){}
^~~~~~~~~
./src/socket/network.h:12:5: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
class Exception {
^~~~~~~~~
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
NetworkException(std::string message){}
^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
Exception(std::string message):message(message){}
^~~~~~~~~
./src/socket/network.h:12:5: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
class Exception {
^~~~~~~~~
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
You need to call the constructor of base class:
class NetworkException:public Exception {
public:
NetworkException(std::string message)
: Exception(message)
{}
};
before the body of ctor of derived class is performed, all data members must be constructed. Exception has only one ctor which takes string, and you have to call it explicitly.

Issue with global variable in class

With the following code, it works "correctly." Meaning it creates the foot instance of WalkerJoint.
#include <WalkerJoint.h>
class WalkerLeg {
//WalkerJoint foot;
// if this is uncommented and the below is reversed it fails
public:
WalkerLeg();
void initLeg();
};
WalkerLeg::WalkerLeg(void) {
WalkerJoint foot(2,3,4,5,6);
//foot(2,3,4,5,6);
//if uncommented with above it fails
}
void initLeg() {
Serial.print("leg init\n");
}
void setup() {
Serial.begin(115200);
while (!Serial) {}
// wait for Serial comms to become ready
}
void loop() {
int bom=0;
WalkerLeg frontLeft;
bom=0;
while(bom++<100000){}
exit(0);
}
However, I need foot to be global so other methods can use it. When I move its declaration into the Class definition it gives the following error:
/Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino: In constructor 'WalkerLeg::WalkerLeg()':
WalkerLeg.cpp:14: error: no matching function for call to 'WalkerJoint::WalkerJoint()'
WalkerLeg::WalkerLeg(void)
^
/Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino:14:26: note: candidates are:
In file included from /Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino:1:0:
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:23:3: note: WalkerJoint::WalkerJoint(int)
WalkerJoint(int); //for using analog inputs
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:23:3: note: candidate expects 1 argument, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:22:3: note: WalkerJoint::WalkerJoint(int, int, int, int, int)
WalkerJoint(int, int, int, int, int);
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:22:3: note: candidate expects 5 arguments, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: constexpr WalkerJoint::WalkerJoint(const WalkerJoint&)
class WalkerJoint
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: candidate expects 1 argument, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: constexpr WalkerJoint::WalkerJoint(WalkerJoint&&)
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: candidate expects 1 argument, 0 provided
WalkerLeg.cpp:18: error: no match for call to '(WalkerJoint) (int, int, int, int, int)'
foot(2,3,4,5,6);
^
exit status 1
no matching function for call to 'WalkerJoint::WalkerJoint()'

No matching function call call to constructor in header file

I have seen similar questions asked and tried their solutions but the answers to them do not seem to work. I have the following code:
.h
#include <iostream>
#include <vector>
#include <string>
using std::string; using std::vector;
struct DialogueNode;
struct DialogueOption {
string text;
DialogueNode *next_node;
int return_code;
DialogueOption(string t, int rc, DialogueNode * nn) : text{t},
return_code{rc}, next_node{nn} {}
};
struct DialogueNode {
string text;
vector <DialogueOption> dialogue_options;
DialogueNode();
DialogueNode(const string &);
};
struct DialogueTree {
DialogueTree() {}
void init();
void destroyTree();
int performDialogue();
private:
vector <DialogueNode*> dialogue_nodes;
};
.cpp
#include "dialogue_tree.h"
DialogueNode::DialogueNode(const string &t) : text{t} {}
void DialogueTree::init() {
string s = "Hello";
for(int i = 0; i < 5; i++) {
DialogueNode *node = new DialogueNode(s);
dialogue_nodes.push_back(node);
delete node;
}
}
void DialogueTree::destroyTree() {
}
int DialogueTree::performDialogue() {
return 0;
}
int main() {
return 0;
}
I get the error: error: no matching function for call to ‘DialogueNode:: DialogueNode(std::__cxx11::string&)’ DialogueNode *node = new DialogueNode(s);
EDIT additional notes on error
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode()
dialogue_tree.h:17:8: note: candidate expects 0 arguments, 1 provided
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode(const DialogueNode&)
dialogue_tree.h:17:8: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const DialogueNode&’
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode(DialogueNode&&)
dialogue_tree.h:17:8: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘DialogueNode&&’
Which makes no sense to me because I have the constructor defined to take a string as an argument.
You've declared your constructor as:
DialogueNode(const string);
But defined it as:
DialogueNode(const string &t);
Those two aren't the same; the former takes a const string while the latter takes a const string reference. You'll have to add the & to specify a reference argument:
DialogueNode(const string &);
it is because in the constructor you are specifying that the parameter will be a string of constant type and when creating an object you are passing a string. The type mismatch is the problem, either fix the constructor parameter to string or change when you are creating an object.

C++ Compiling Issues

When compiled using g++ MainStudent.cpp Student.cpp
These are the errors i get :
MainStudent.cpp: In function ‘int main()’: MainStudent.cpp:23:38:
error: no matching function for call to ‘Student::Student(char [10],
char [10], int&, double [3])’ MainStudent.cpp:23:38: note: candidates
are: Student.h:13:2: note: Student::Student(char*, char*, int, double)
Student.h:13:2: note: no known conversion for argument 4 from
‘double [3]’ to ‘double’ Student.h:5:7: note: Student::Student(const
Student&) Student.h:5:7: note: candidate expects 1 argument, 4
provided Student.cpp: In constructor ‘Student::Student(char*, char*,
int, double)’: Student.cpp:9:11: error: incompatible types in
assignment of ‘double’ to ‘double [3]’ Student.cpp: At global scope:
Student.cpp:14:5: error: prototype for ‘int Student::Getage()’ does
not match any in class ‘Student’ Student.h:16:7: error: candidate is:
int* Student::Getage() Student.cpp:15:8: error: prototype for ‘double
Student::Getmarks()’ does not match any in class ‘Student’
Student.h:17:10: error: candidate is: double* Student::Getmarks()
I can't figure out where the problem lies...
Your constructor is
Student::Student (char *fname, char *lname, int age, double marks)
^^^^^^^^^^^^
But you are trying to pass an array to it in
double marks[3];
//...
Student st1(fname, lname, age, marks);
You either need to get rid of the array in the class and just take a double or change the constructor to take a double array and then copy it in the constructor like
Student::Student (char *fname, char *lname, int age, const double (&marks)[3]) {
// ^^^^^^^^^^^^^^^ use array of size 3
// since that is what _marks is
strcpy(_fname, fname);
strcpy(_lname, lname);
_age = age;
for (int i = 0; i < 3; i++)
_marks[i] = marks[i];
}