I've got a class Foo, which have a main function and execute function. I want to start an unknown number of threads with the execute function, but when I try to compile the code I always get error C2064: term does not evaluate to a function taking 1 arguments.
foo.h
#ifndef BOT_H
#define BOT_H
#pragma once
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string>
class foo
{
public:
foo(char *_server, char *_port);
~foo(void);
private:
char *server;
char *port;
void execute(char *cmd);
void main();
};
#endif
foo.c
#include <thread>
#include "bot.h"
#include "definitions.h"
using namespace std;
foo::foo(char *_server, char *_port){
...
}
bot::~bot(void) {
...
}
void bot::execute(char *command){
...
}
void bot::main(){
thread(&bot::execute, (char*)commanda.c_str()).detach();
}
How should I create threads from class member functions?
Thanks for any answer
You need a bot object to call the member function on:
thread(&bot::execute, this, (char*)commanda.c_str())
^^^^
although you really should either change the function to take either std::string or const char*. You have a minefield of undefined behaviour here, if either the function tries to modify the string, or commanda is destroyed while the thread is still using it.
A lambda may be more readable; and would also fix the lifetime fiasco by capturing a copy of the string:
thread([=]{execute((char*)commanda.c_str();})
Related
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
Using C++14, I'm trying to define a variable in a namespace where commonly used variables are stored (App::Common). The main function should be the one that sets it, since it gets set to argv[0]. Meanwhile I need the variable to be visible by all other classes/files. But I get the linker error shown below. Also, ideally I would like the variable to be const where only the main function would set it once.
common.hpp
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
main.cpp
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
client.hpp
#include "common.hpp"
class Client {
public:
void printAppPath();
};
client.cpp
#include <iostream>
#include <string>
#include "common.hpp"
#include "client.hpp"
void Client::printAppPath() {
std::cout << App::Common::appPath << std::endl;
}
I get the following error by the linker:
ld: main.o: in function `main':
main.cpp:(.text.startup.main+0x25): undefined reference to `App::Common::appPath[abi:cxx11]'
ld: Client.o: in function `Client::printAppPath()':
Client.cpp:(.text...): undefined reference to `App::Common::appPath[abi:cxx11]'
This
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
contains only declaration of the variable appPath without its definition.
Here
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
there is used the assignment operator to assign a value tp the variable appPath as if it were already defined. However actually its definition does not yet exist.
You can define the variable in any module in any enclosing namespace of the namespace Common or inside the namespace. For example you could define it in client.cpp like
std::string App::Common::appPth;
You are mixing definition and assignment, which are two different things for a variable:
a declaration for a variable x tells your compiler that there exists somewhere a variable named x;
a definition for a variable x tells your compiler that it needs to reserve some space for this variable x, and that the variable x will live at this location;
an assignment assigns a value to a variable.
For a variable, a declaration is usually a definition:
void foo() {
int a; // Declaration AND Definition!
}
...except when the variable is marked as extern, since extern explicitly tells the compiler that this variable is defined elsewhere. In your case, this:
namespace App::Common { // C++17 style
extern std::string appPath;
}
...is a declaration, but this:
namespace App::Common { // C++17 style
std::string appPath;
}
...would be a definition (and also a declaration), and this:
int main(int argc, char *argv[]) {
App::Common::appPath = std::string(argv[0]);
}
...is an assignment.
You should not define appPath in a header such as common.hpp, otherwize, you will have multiple definitions of the same variable (one for each .cpp file that includes your common.hpp) and the program will fail to compile.
What you want is a single definition for your program, and the only way to obtain it is to define App::Common::appPath once-and-for-all in a .cpp file. You can define it in main.cpp if you want:
#include <string>
#include "common.hpp"
#include "client.hpp"
// Definition:
std::string App::Common::appPath;
int main() {
// Assignment:
App::Common::appPath = argv[0];
}
You need definition:
in Common.cpp:
namespace App{
namespace Common{
std::string appPath;
}
}
To create my EventManager, I needed to create functions which would take shared_ptr of Listeners to store them into vectors and call their event function.
I did so, and it works correctly, unless when I close my program.
When closing it, the program crashes, saying "double free or corruption". I understood my problem came from my std::shared_ptr(this). So I tried to use shared_from_this... but it doesn't really seem to work.
main.cpp :
#include "Game.h"
#include "EventManager.h"
int main() {
EventManager evManager;
std::shared_ptr<Game> game(new Game(&evManager));
return 0;
}
Game.h & Game.cpp :
#ifndef GAME_H
#define GAME_H
#include "EventManager.h"
#include <memory>
class EventManager;
class Game : public std::enable_shared_from_this<Game>
{
public:
Game(EventManager* evManager);
};
#endif // GAME_H
#include "Game.h"
Game::Game(EventManager* evManager) {
evManager->addGame(shared_from_this());
}
EventManager.h & EventManager.cpp
#ifndef EVENTMANAGER_H
#define EVENTMANAGER_H
#include <memory>
#include "Game.h"
class Game;
class EventManager
{
public:
void addGame(std::shared_ptr<Game> game);
protected:
std::shared_ptr<Game> m_game;
};
#endif // EVENTMANAGER_H
#include "EventManager.h"
void EventManager::addGame(std::shared_ptr<Game> game) {
m_game = game;
}
I executed my program with hope it would work, but I got a std::bad_weak_ptr. This error seems to occur when you try to create a shared_ptr from something that no longer exists.
So I thought it could be that the program ended too fast for the shared_ptr to create. Unfortunately it's not the problem, I added a std::cout after the creation of the Game class and it never shows, the program crashes before.
I hope you understand my problem and can help me solve it,
Cheers.
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this
Notes
It is permitted to call shared_from_this only on a previously shared object, i.e. on an object managed by std::shared_ptr. Otherwise the behavior is undefined (until C++17)std::bad_weak_ptr is thrown (by the shared_ptr constructor from a default-constructed weak_this) (since C++17).
you call shared_from_this in constructor when there's no shared_ptr yet
I'm trying to create a simple CPU simulator.
The CPU class has a hash_map<uint8_t, Instruction> instructionTable; and within the CPU constructor I would like to create all the Instruction objects and insert them into instructionTable.
Instruction.h:
#ifndef INSTRUCTION_H
#define INSTRUCTION_H
#include <cstdint>
#include <string>
#include "CPU.h"
class Instruction
{
public:
uint8_t opcode;
Instruction();
void(*execute)(CPU* cpu);
};
#endif
CPU.h:
#ifndef CPU_H
#define CPU_H
#include <cstdint>
#include <unordered_map>
#include "Instruction.h"
#include "Memory.h"
class CPU
{
public:
Memory* memory;
CPU(Memory* memory);
void loadInstructionSet();
};
#endif
CPU.cpp:
#include "stdafx.h"
#include "CPU.h"
#include <string>
#include <iostream>
CPU::CPU(Memory* memory){
this->memory = memory;
}
void CPU::loadInstructionSet(){
Instruction *LDA = new Instruction();
LDA->execute = [](CPU*) { std::cout << "execute LDA..."; };
}
How can I now create Instruction objects and assign a new execute function?
I thought lambda expressions / anonymous functions are used for such things.
This line:
void *(execute)(CPU* cpu);
is a function declaration. To declare a function pointer, use
void (*execute)(CPU* cpu);
Cannot convert from void to void (__cdecl *)(void)
This is because you call your lambda, and its return expression is absent i.e. equals to void. Remove last bracket:
LDA->execute = []() { cout << "execute LDA..."; };
Note also that a lambda can only be converted to a function pointer if it does not capture.
Prefer to use std::function instead of raw function pointers.
LDA->execute = { cout << "execute LDA..."; }();
This should be
LDA->execute = [](CPU*) { cout << "execute LDA..."; };
First, with the brackets at the end of the line you're actually calling the lambda right after creating it.
Second, the type definition of execute says that the function expects a pointer to CPU, but in the lambda you take the CPU by value and not by a pointer.
I'm current building an application in which I have a log function that is accessible in most of my classes which was declared as below:
FileHandler.h
#ifndef FILEHANDLER_H
#define FILEHANDLER_H
#pragma once
#include <SDL.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cctype>
//Include to allow logging
#include "log.h"
class fileHandler
{
public:
fileHandler();
virtual ~fileHandler();
void WriteToFile(const std::string& filename, std::string textToWrite);
std::vector<std::string> ReadFromFile(const std::string& filename);
std::string& TrimString(std::string& stringToTrim);
protected:
private:
class log logHandler;
std::vector<std::string> blockOfText;
std::string currentLine;
};
#endif // FILEHANDLER_H
Log.h
#ifndef LOG_H
#define LOG_H
#pragma once
#include <SDL.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
class log
{
public:
log();
virtual ~log();
void static WriteToConsole(std::string textToWrite);
void WriteToLogFile(std::string textToWrite);
protected:
private:
};
#endif // LOG_H
This worked fine for a long time and then I wanted to include another function elsewhere in my application that was only compatible with C++11 so I told the compiler to compile to these standards. I was then receiving an error on "log logHandler" saying log is not a declared name.
I was able to resolve the problem by changing the line to
class log logHandler;
I was wondering if anybody could tell me what has changed between C++03 and C++11 that required me to do this?
EDIT: Included all relevant code to make question more complete.
You don't show your real code (missing ; at the end of the class declaration, no #endif), but chances are that your problem is somehow related to std::log, which has received a new overload in C++11, in combination with a using namespace std somewhere in your code.
Note that the new overload is probably irrelevant to the problem at hand; the real reason may very well be a change somewhere in your compiler's standard-library implementation causing an internal #include <cmath>. This means that even in C++03, your code was only working by sheer coincidence, and a conforming C++03 compiler was always allowed to reject it.
Here is an example program which may reproduce your problem:
#include <cmath>
using namespace std;
struct log
{
};
int main()
{
// log l; // does not compile
struct log l; // compiles
}
Nothing has changed about how the code you posted is treated.
What I suspect is, that you somewhere have an
#include <cmath>
And below that, somewhere else
using namespace std;
This causes your compiler to not be able to unambiguously resolve the name log, since there is std::log (a function) and your class log.
By explicitly stating class log, you tell the compiler that you are referring to the class.
Could any body offer me any reason about that?
If we do it like that, what's the outcome? Compile error?
The problem is that static initialization isnt just initialization, it is also definition. Take for example:
hacks.h :
class Foo
{
public:
static std::string bar_;
};
std::string Foo::bar_ = "Hello";
std::string GimmeFoo();
main.cpp :
#include <string>
#include <sstream>
#include <iostream>
#include "hacks.h"
using std::string;
using std::ostringstream;
using std::cout;
int main()
{
string s = GimmeFoo();
return 0;
}
foo.cpp :
#include <string>
#include <sstream>
#include <iostream>
#include "hacks.h"
using std::string;
using std::ostringstream;
using std::cout;
string GimmeFoo()
{
Foo foo;
foo;
string s = foo.bar_;
return s;
}
In this case, you can't initialize Foo::bar_ in the header because it will be allocated in every file that #includes hacks.h. So there will be 2 instances of Foo.bar_ in memory - one in main.cpp, and one in foo.cpp.
The solution is to allocate & initialize in just one place:
foo.cpp :
...
std::string Foo::bar_ = "Hello";
...
It is just a limitation in the language it self. Hopefully, when C++0x becomes reality, this limitation would go away.
I think this page gives a somehow good reason:
One of the trickiest ramifications of
using a static data member in a class
is that it must be initialized, just
once, outside the class definition, in
the source file. This is due to the
fact a header file is typically seen
multiple times by the compiler. If the
compiler encountered the
initialization of a variable multiple
times it would be very difficult to
ensure that variables were properly
initialized. Hence, exactly one
initialization of a static is allowed
in the entire program.