sorry for the verbosity - I did my best to condense my code sample into a minimally functional class and main() method.
I'm trying to use an atomic_flag to notify _rx() within my worker thread to quit when stop() is called.
I believe the issue is in trying to create my worker thread,
thread SanityTestThread(&SanityTest::_rx, *this);
which somehow clashes with my atomic_flag
code sample (does not compile):
#include <cstdio>
#include <chrono>
#include <unistd.h>
#include <atomic>
#include <iostream>
#include <thread>
using namespace std;
class SanityTest
{
public:
SanityTest(){}
void start();
void stop();
private:
void _rx();
atomic_flag flag;
}; // end class SanityTest
void SanityTest::_rx()
{
while(flag.test_and_set())
{
this_thread::sleep_for(chrono::seconds(1));
cout << "'sup foo" << endl;
}
} // end _rx
void SanityTest::start()
{
flag.test_and_set();
thread SanityTestThread(&SanityTest::_rx, *this);
SanityTestThread.detach();
} // end start
void SanityTest::stop()
{
flag.clear();
} // end start
int main(){
SanityTest s;// = SanityTest();
s.start();
this_thread::sleep_for(chrono::seconds(10));
s.stop();
return 0;
} // end main
For the record, I can get my program to compile and run by removing all references to my atomic_flag and replacing my _rx() loop with a for loop like so:
void SanityTest::_rx()
{
for(int i=0; i <=10; ++ i)
{
this_thread::sleep_for(chrono::seconds(1));
cout << "'sup foo" << endl;
}
} // end _rx
Compiler Error:
In file included from ./SanityTest.cpp:1:0:
./SanityTest.hpp:14:7: note: ‘SanityTest::SanityTest(SanityTest&&)’ is implicitly deleted because the default definition would be ill-formed:
class SanityTest
^
./SanityTest.hpp:14:7: error: use of deleted function ‘std::atomic_flag::atomic_flag(const std::atomic_flag&)’
In file included from /usr/include/c++/4.8/atomic:41:0,
from ./SanityTest.hpp:8,
from ./SanityTest.cpp:1:
/usr/include/c++/4.8/bits/atomic_base.h:275:5: error: declared here
atomic_flag(const atomic_flag&) = delete;
^
In file included from /usr/include/c++/4.8/functional:55:0,
from /usr/include/c++/4.8/thread:39,
from ./SanityTest.hpp:10,
from ./SanityTest.cpp:1:
...
In file included from ./SanityTest.cpp:1:0:
./SanityTest.hpp:14:7: note: ‘SanityTest::SanityTest(SanityTest&&)’ is implicitly deleted because the default definition would be ill-formed:
class SanityTest
^
./SanityTest.hpp:14:7: error: use of deleted function ‘std::atomic_flag::atomic_flag(const std::atomic_flag&)’
In file included from /usr/include/c++/4.8/atomic:41:0,
from ./SanityTest.hpp:8,
from ./SanityTest.cpp:1:
/usr/include/c++/4.8/bits/atomic_base.h:275:5: error: declared here
atomic_flag(const atomic_flag&) = delete;
^
In file included from /usr/include/c++/4.8/functional:55:0,
from /usr/include/c++/4.8/thread:39,
from ./SanityTest.hpp:10,
from ./SanityTest.cpp:1:
p.s. This is compiled with, g++ -pthread -std=c++0x -o SanityTest ./SanityTest.cpp
Just replace
thread SanityTestThread(&SanityTest::_rx, *this);
with
thread SanityTestThread(&SanityTest::_rx, this);
You probably intended to pass a pointer to the object and not the object itself (which would result in that object being copied and the member function pointer &SanityTest::_rx being invoked on that copy instead of the original object).
The reason for the error message is essentially that std::atomic_flag doesn't have a copy constructor and so the compiler doesn't generate a default one for your SanityTest class either, but again: you don't want to copy your SanityTest object here anyway.
Related
I am trying to create a class which can read input from either a file stream or std::cin:
#include <string>
#include <iostream>
#include <mutex>
class A
{
public:
explicit A(std::istream& input)
: input_(input)
{
;
}
public:
void doSomething()
{
std::string word;
while (input_ >> word) {
std::cout << word << std::endl;
}
}
private:
std::istream& input_;
std::mutex mutex_;
};
int main()
{
auto a = A(std::cin);
a.doSomething();
return 0;
}
But the compiler gives the following output:
~/test/main.cpp: In function ‘int main()’:
~/test/main.cpp:31:22: error: use of deleted function ‘A::A(A&&)’
auto a = A(std::cin);
^
~/test/main.cpp:5:7: note: ‘A::A(A&&)’ is implicitly deleted because the default definition would be ill-formed:
class A
^
~/test/main.cpp:5:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from /usr/include/c++/7/mutex:43:0,
from ~/test/main.cpp:3:
/usr/include/c++/7/bits/std_mutex.h:97:5: note: declared here
mutex(const mutex&) = delete;
^~~~~
How should I fix the error? Or generally, how do we create a class that can read input either from a file stream or std::cin?
Edit
Initially I tried to reduce the amount of code as much as possible, and in that process, I removed std::mutex part, which gave a very different compiler output. Plus, there was a typo where input_ was std::stream and #JerryJeremiah was correct in the first comment that it should be std::istream &.
Now, I think the question doesn't quite match the problem, as #acraig5075 also pointed out in the comment. And there are similar questions on Stack Overflow already, so I'm going to delete my question.
I found the answer.
std::mutex is not copyable, and the class containing it becomes not-copyable as well.
The code should be:
int main()
{
A a(std::cin);
a.doSomething();
return 0;
}
There's the main.cpp that has lots of Log prinkled wherever:
#include "utils.hpp"
...//some code
int main(){
int a = 0;
int b = 0;
util::LogClass::Log("Initial","something);
//some more code
util::LogClass::Log("Mid","something");
//some more code
util::LogClass::Log("Middle","something");
}
And the LogClass is defined like this in utils.hpp:
namespace util{
class LogClass{
public:static bool LOG_ENABLED;
public: static void Log(std::string tag, std::string message){
if(LOG_ENABLED){
std::cerr << tag+": "+message <<std::endl;}
}
}
bool LogClass::LOG_ENABLED=true;
}
I was thinking I would be able to do this in main.cpp:
#include "utils.cpp"
util::LogClass::LOG_ENABLE=false;
int main(){ //the previous main function}
*the above code actuallly gives an error saying: redefinition of ‘bool util::LogClass::LOG_ENABLED’
bool util::LogClass::LOG_ENABLE=false *
but, if I move it inside the main:
#include "utils.cpp"
int main(){ util::LogClass::LOG_ENABLED=false; //the previous main function}
then the code compiles fine. So my question is why can't I enable it outside the main() function even if it is a static member, and why does the (g++) compiler takes it as a redefinition?
You can only statically initialize a variable at the point where it is getting defined. The initialization inside the main function is dynamic, so that's fine.
I agree that the compiler error is weird though - the compiler might be trying to auto-deduct the "missing" type that should be there for a redefinition.
So I am trying do do some multithreading in c++, I am trying to use the std::thread. All examples I can find on the internet use the main method. But I want to create a thread in a class constructor, and join the thread in the destructor and then clean up the thread. I have tried several things like this:
.cpp:
#inlcude "iostream"
myClass::myClass()
{
myThread= new std::thread(threadStartup, 0);
}
myClass::~myClass()
{
myThread->join();
delete myThread;
}
void threadStartup(int threadid)
{
std::cout << "Thread ID: " << threadid << std::endl;
}
.h
#pragma once
#include "thread"
class myClass
{
public:
myClass();
~myClass();
private:
std::thread* myThread;
};
This gives me the following error error: C2065: 'threadStartup': undeclared identifier. I have also tried to add the thread startup method to the class, but that gives me a whole lot more errors.
I cant figure this out, any help would be appreciated.
EDIT: std::thread has been changed to std::thread* like in my code.
If I move the function declaration of threadStartup to the top of my file I get the errors:
Severity Code Description Project File Line Suppression State
Error C2672 'std::invoke': no matching overloaded function found
And
Severity Code Description Project File Line Suppression State
Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
Cannot reproduce. Please, see my sample code test-thread.cc:
#include <iostream>
#include <thread>
class MyClass {
private:
std::thread myThread;
public:
MyClass();
~MyClass();
};
void threadStartup(int threadid)
{
std::cout << "Thread ID: " << threadid << std::endl;
}
MyClass::MyClass():
myThread(&threadStartup, 0)
{ }
MyClass::~MyClass()
{
myThread.join();
}
int main()
{
MyClass myClass;
return 0;
}
Tested in cygwin64 on Windows 10 (64 bit):
$ g++ --version
g++ (GCC) 5.4.0
$ g++ -std=c++11 -o test-thread test-thread.cc
$ ./test-thread
Thread ID: 0
$
Please, notice that I don't use new (as its not necessary in this case).
C++ is parsed top down ans since your threadStartup function is declared after you use it, the compiler cannot find it. Declare threadStartup before you use it and you should be ok.
I am pursuing some interest in c++ programming by way of self instruction. I am working on some basic stuff for now and am currently having issue getting my classes talking/instantiated?.
I am trying to get my main cpp file to compile alongside a header and call to some class functions through the main using a more efficient command method.
I am stuck and would appreciate some help. I will include both files. I am just trying to get a return value from the header by calling the function.
error:
main.cpp:6.21 error: cannot call member function 'void myClass::setNumber(int) without object
the code works when compiled with the main, so it is something with the 'scope resolution operator' i think. First is main.cpp
#include <iostream>
#include "myClass.h"
using namespace std;
int main(){
myClass::setNumber(6);
{
return number;
}
}
Then my header file myClass.h
// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class myClass {
private:
int number;//declares the int 'number'
float numberFloat;//declares the float 'numberFloat
public:
void setNumber(int x) {
number = x;//wraps the argument "x" as "number"
}
void setNumberFloat(float x) {
numberFloat = x;
}
int getNumber() {//defines the function within the class.
number += 500;
return number;
}
float getNumberFloat() {//defines the function
numberFloat *= 1.07;
return numberFloat;
}
};
#endif
Any help?
The error message says everything:
cannot call member function 'void myClass::setNumber(int)' without object
You need to create an object first:
myClass obj;
then call the class method on that object:
obj.setNumber(6);
The value 6 will get assigned to the number field of the obj variable.
I am trying to implement an execution pattern which takes any function and executes it with its own conditions/preparations. Regardless of this being a useful thing to do, it just doesn't work. It seems i can't access the template overload of the "Execute"-function (called in "main").
Specifically: Why can't i call the overloaded template function of Execute?
This is the full program:
#include "stdafx.h"
#include <functional>
class TransparentFunctionWrapper
{
public:
virtual void Execute(std::function<void()> executeFunction) = 0;
template<class C>
C Execute(std::function<C(void)> executeFunction) // template-overload of the abstract function which will implicitly call it
{
C ret;
Execute( // calls the abstract function with a lambda function as parameter
[ret, executeFunction](void) -> C // lambda declaraction
{ //
ret = executeFunction; // lambda body
}); //
return ret;
}
};
class ExampleExecutor : public TransparentFunctionWrapper
{
public:
virtual void Execute(std::function<void()> executeFunction)
{
printf("executed before.");
executeFunction();
printf("executed after.");
}
};
void DoStuff() {}
int ReturnStuff() { return -5; }
int main()
{
ExampleExecutor executor;
executor.Execute(DoStuff);
int i = executor.Execute<int>(ReturnStuff); // Why does this not work? ERROR: "type name is not allowed"
getchar();
return 0;
}
Note: Visual Studio marks
Execute<int>(ReturnStuff) // "int" is marked as Error: type name is not allowed
The compilation puts out the error
"type 'int' unexpected"
Thanks to everyone willing to help!
ExampleExecutor::Execute is not overriding TransparentFunctionWrapper::Execute, and it is hiding it in the executor.Execute<int> call.
You must explicitly call TransparentFunctionWrapper::Execute, as it is hidden by ExampleExecutor::Execute. Here's a possible way of doing that:
int i = executor.TransparentFunctionWrapper::Execute<int>(ReturnStuff);
live example on coliru