No viable conversion from 'shared_ptr<Pin>' to 'shared_ptr<Component>s' - c++11

I have an assignment of creating a Circuit Sim and I'm having issues with NotGate class when I try to use it.
Components is an abstract class.
class Component
{
public:
virtual bool getOutput() = 0;
virtual void prettyPrint(string padding) = 0;
virtual void linearPrint() = 0;
};
Then I have Pin and NotGate, they inherit through dependency of Components.
class Pin {
private:
bool value;
string label;
public:
Pin::Pin(string theLabel) {
label = theLabel;
}
bool Pin::getOutput() {
return value;
}
void Pin::setValue(bool newVal) {
this->value = newVal;
}
};
class NotGate {
private:
shared_ptr<Component> input;
public:
NotGate::NotGate() {
input = make_shared<Component>();
}
bool NotGate::getOutput() {
if (input == 0) {
return true;
} else {
return false;
}
}
void NotGate::setInput(shared_ptr<Component> in) {
this->input = in;
}
};
I created a Pin "c" and a notGate "n1", I want to have "c" as the input for "n1". When I try to do it with the command:
n1->setInput(c);
It tells me that: No viable conversion from 'shared_ptr<Pin>' to 'shared_ptr<Component>s'
I tried creating a new shated_ptr of Components and a bunch of different things that didn't work.

The error message from the compiler is clear. If you want to be able to use a shared_ptr<Pin> when a shared_ptr<Component> is expected, you should make Pin a sub-class of Component. From an abstraction standpoint, it makes sense to me that Pin be a sub-class of Component.
class Pin : public Component
{
...
};

Related

How to get a reference to the negation of a bool?

For example, if I have a bool value v, I want a reference to !v that can change when v changes. An example use will be:
class A {
bool& isOpen;
A(bool& value): isOpen(value) {}
void f() {
if (isOpen) {
doSomething();
}
}
};
class B {
bool& isClosed;
B(bool& value): isClosed(value) {}
void g() {
if (isClosed) {
doSomething();
}
}
};
int main() {
bool isOpen = true;
A a(isOpen);
B b(negattive_reference_of(isOpen));
a.f(); // doSomething()
b.g(); // do nothing
isOpen = false;
a.f(); // do nothing
b.g(); // doSomething()
}
Is there anyway in C++ to acheive a similar effect?
Under the hood reference is equivalent to a constant pointer to some variable (compiler just gives you a syntax sugar of how to work with such pointers so that they are always initialized).
So you wan't to have the same variable and two different pointers to it, one of which will dereference to true and the other to false. That is obviously impossible.
The OOP -way to do it would be to pass not reference to boolean but some interface to your classes and use implementation that uses same boolean variable:
class IIsOpenProvider
{
public:
virtual ~IIsOpenProvider() = 0;
virtual bool GetOpenValue() = 0;
};
class IIsClosedProvider
{
public:
virtual ~IIsClosedProvider() = 0;
virtual bool GetClosedValue() = 0;
};
class ValueProvider : public IIsOpenProvider, public IIsClosedProvider
{
public:
bool GetOpenValue() override { return isOpen; }
bool GetClosedValue() override { return !isOpen; }
private:
bool isOpen;
};
class A {
IIsOpenProvider& isOpen;
A(IIsOpenProvider& value): isOpen(value) {}
void f() {
if (isOpen.GetOpenValue()) {
doSomething();
}
}
};
class B {
IIsClosedProvider& isClosed;
B(IIsClosedProvider& value): isClosed(value) {}
void g() {
if (IIsClosedProvider.GetClosedValue()) {
doSomething();
}
}
};
// usage
ValueProvider val;
A a(val);
B b(val);

queue of different class objects

I need to create a queue of different class objects (These classes are not related). I found a solution as follows:
Create a base class and use polymorphism.
Here is how I implemented it,
class Task {
public:
virtual void operator()() {
printf("should not be called\n");
}
};
class TaskRPCB : public Task {
private:
int x;
// other varibles
std::function<void(int)> func;
public:
TaskRPCB(std::function<void(int)>&f , int x) {
this->func = f;
this->x = x;
}
void operator()() {
printf("TaskRPCB function is executing...\n");
func(x);
}
};
class TaskECB : public Task {
private:
// other varibles
std::function<void(void)> func;
public:
TaskECB(std::function<void(void)>&f) : func(f) {}
void operator()() {
printf("TaskECB function is executing...\n");
func();
}
};
void F1() { // dummy function for example
cout <<"no x"<<endl;
}
void F2(int x) { // dummy function for example
cout <<"x : "<<x<<endl;
}
int main() {
queue<unique_ptr<Task>> Q;
function<void()> func1 = F1;
function<void(int)> func2 = F2;
TaskECB task1(func1);
TaskRPCB task2(func2,4);
Q.emplace(new TaskECB(func1));
Q.emplace(new TaskRPCB(func2,4));
(*Q.front())();
Q.pop();
(*Q.front())();
Q.pop();
}
The problem is, I can not push the objects directly as shown above. I have to create an object of an inherited class and pass it to another function to do the push action. It is because ( in my case ) the queue is a part of a thread-safe queue and it has separate Push() method.
template<typename T>
void threadSafeQueue<T>::Push(T newData) { /* TODO: size check before pushing */
std::shared_ptr<T> data(std::make_shared<T>(std::move(newData)));
/* construct the object before lock*/
std::lock_guard<std::mutex> lk(mut);
taskQueue.push(data);
dataCond.notify_one();
}
Earlier I did not have multiple tasks to execute ( or push ) into the queue, therefore
threadSafeQueue<TaskRPCB> workQ declaration worked fine for me.
Creating a base Task class like above is not working because of object slicing
Can you suggest other ways to store objects in the queue ( so that I can still use the lock guarded Push() method )
Thanks !
update :
is the correct way of using variant?
typedef std::variant<TaskECB, TaskRPCB> myType;
int main() {
queue<unique_ptr<myType>> Q;
function<void()> func1 = F1;
function<void(int)> func2 = F2;
TaskECB task1(func1);
TaskRPCB task2(func2,4);
myType x = task1;
Q.push(make_unique<myType>(x));
x = task2;
Q.push(make_unique<myType>(x));
if((*Q.front()).index() == 0) {
auto f1 = get<TaskECB>(*Q.front());
f1();
Q.pop();
}
if((*Q.front()).index() == 1) {
auto f1 = get<TaskRPCB>(*Q.front());
f1();
Q.pop();
}
}
update2:
using myVariantType = std::variant<TaskECB, TaskRPCB>;
struct VisitPackage {
void operator()(TaskECB & task) {
task();
}
void operator()(TaskRPCB& task) {
task();
}
};
int main() {
queue<myVariantType> Q;
function<void()> func1 = F1;
function<void(int)> func2 = F2;
TaskECB task1(func1);
TaskRPCB task2(func2,4);
Q.emplace(task1);
Q.emplace(task2);
std::visit(VisitPackage(), Q.front());
Q.pop();
std::visit(VisitPackage(), Q.front());
Q.pop();
}

c++ thread pool with mutable threads: strange deadlock when assigning tasks to threaads

hope you had all had nice holidays.
This questions is related to my earlier question: std::condition_variable - Wait for several threads to notify observer
I'm trying to implement a threadpool based on my own mutable thread implementation below:
class MutableThread
{
private:
std::thread m_Thread;
std::function<void()> m_Function;
bool m_bRun;
std::mutex m_LockMutex;
std::mutex m_WaitMutex;
std::condition_variable m_CV;
IAsyncTemplateObserver<MutableThread>* m_Observer = nullptr;
private:
void Execute()
{
while (m_bRun)
{
{
std::unique_lock<std::mutex> wait(m_WaitMutex);
m_CV.wait(wait);
}
std::lock_guard<std::mutex> lock(m_LockMutex);
if (m_bRun && m_Function)
{
m_Function();
m_Function = std::function<void()>();
if (m_Observer != nullptr)
{
m_Observer->Signal(this);
}
}
}
}
public:
HDEBUGNAME(TEXT("MutableThread"));
MutableThread(const MutableThread& thread) = delete;
MutableThread(IAsyncTemplateObserver<MutableThread>* _Observer)
{
m_Observer = _Observer;
m_bRun = true;
m_Thread = std::thread(&MutableThread::Execute, this);
}
MutableThread()
{
m_Observer = nullptr;
m_bRun = true;
m_Thread = std::thread(&MutableThread::Execute, this);
}
~MutableThread()
{
m_bRun = false;
m_CV.notify_one();
try
{
if (m_Thread.joinable())
m_Thread.join();
}
catch (std::system_error& ex)
{
HWARNINGD(TEXT("%s"), ex.what());
}
}
inline bool Start(const std::function<void()>& f)
{
std::lock_guard<std::mutex> lock(m_LockMutex);
if (m_Function != nullptr)
return false;
m_Function = f;
m_CV.notify_one();
return true;
}
The IAsyncTemplateObserver simply derives from my IAsyncObserver class posted in the earlier question and adds a virtual function:
template <typename T>
class IAsyncTemplateObserver : public IAsyncObserver
{
public:
virtual void Signal(T* _Obj) = 0;
};
What I want to do is, signal the ThreadPool that the function has finished execution and a new task is assigned to the mutable thread:
class MutableThread;
struct Task
{
std::function<void()> m_Function;
uint32_t m_uPriority;
Task(const std::function<void()>& _Function, uint32_t _uPriority)
{
m_Function = _Function;
m_uPriority = _uPriority;
}
};
inline bool operator<(const Task& lhs, const Task& rhs)
{
return lhs.m_uPriority < rhs.m_uPriority;
}
class ThreadPool : public IAsyncTemplateObserver<MutableThread>
{
private:
std::list<MutableThread* > m_FreeThreads;
std::list<MutableThread* > m_UsedThreads;
std::set<Task> m_Tasks;
std::mutex m_LockMutex;
public:
ThreadPool()
{
//Grow(std::thread::hardware_concurrency() - 1);
}
ThreadPool(size_t n)
{
Grow(n);
}
~ThreadPool()
{
//std::lock_guard<std::mutex> lock(m_Mutex);
for (MutableThread* pUsed : m_UsedThreads)
{
HSAFE_DELETE(pUsed);
}
for (MutableThread* pFree : m_FreeThreads)
{
HSAFE_DELETE(pFree);
}
}
inline void Grow(size_t n)
{
std::lock_guard<std::mutex> lock(m_LockMutex);
for (size_t i = 0; i < n; i++)
{
m_FreeThreads.push_back(new MutableThread(this));
}
}
inline void AddTask(const Task& _Task)
{
{
std::lock_guard<std::mutex> lock(m_LockMutex);
m_Tasks.insert(_Task);
}
AssignThreads();
}
virtual void Signal(MutableThread* _pThread)
{
{
std::lock_guard<std::mutex> lock(m_LockMutex);
m_UsedThreads.remove(_pThread);
m_FreeThreads.push_back(_pThread);
}
AssignThreads();
NotifyOne();
}
inline void WaitForAllThreads()
{
bool bWait = true;
do
{
{
//check if we have to wait
std::lock_guard<std::mutex> lock(m_LockMutex);
bWait = !m_UsedThreads.empty() || !m_Tasks.empty();
}
if (bWait)
{
std::unique_lock<std::mutex> wait(m_ObserverMutex);
m_ObserverCV.wait(wait);
}
} while (bWait);
}
private:
inline void AssignThreads()
{
std::lock_guard<std::mutex> lock(m_LockMutex);
if (m_FreeThreads.empty() || m_Tasks.empty())
return;
//Get free thread
MutableThread* pThread = m_FreeThreads.back();
m_FreeThreads.pop_back();
//park thread in used list
m_UsedThreads.push_back(pThread);
//get task with highest priority
std::set<Task>::iterator it = m_Tasks.end();
--it; //last entry has highest priority
//start the task
pThread->Start(it->m_Function);
//remove the task from the list
m_Tasks.erase(it);
}
The AddTask function is called several times by the same thread, but when a mutable thread signals the threadpool (via m_Observer->Signal(this) ) the application freezes at the lock_guard of the AssignThreads() function. Now the strange thing is unlike a normal deadlock, all callstack-views in Visual Studio are empty as soon is I try to step over the line with the lock_guard.
Can anyone explain this behaviour? Is there any major design flaw or just a simple mix up?
Thanks for your help!
Greetings,
Fabian
Edit: I've added a minimal visual studio solution that reproduces the problem: ThreadPoolTest.zip
Thanks to a friend, I was able to fix the problem by moving the call m_Observer->Signal(this) outside of the lock_guard scope in the MutableThread::Execute() function. Secondly I removed the lock_guard in the AssignThreads() function and moved its call into the scope of the lock_guard in the Signal()/AddTask function. Not really related but still a flaw: all condition_variables.wait() calls are now in a while(m_bNotified == false) loop.

C++/CLI managed class member callback by managed code

I am designing a class in C++/CLR that uses a callback function provided by user code.
This works very nicely if the callback function is free ( i.e. not the member of a class ). It is almost the same as in pure C++.
Here is some sample code that works well:
ref class ClassThatUsesCallback
{
public:
typedef void (*callback_t)( String^ );
void setCallback( callback_t pfun )
{
myCallback = pfun;
}
void Run()
{
if( myCallback != nullptr ) {
myCallback("This is a test");
}
}
private:
callback_t myCallback;
};
void FreeFunction( String^ s )
{
Console::WriteLine( "Free Function Callback " + s );
}
int main(array<System::String ^> ^args)
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback( FreeFunction );
theClassThatUsesCallback->Run();
}
However, I would like the callbacked function to be a member of a class in the user code ( so it can make use of and change the attributes of the user code class )
The following code does not compile
ref class ClassThatProvidesCallback
{
public:
void MemberFunction( String^ s )
{
Console::WriteLine( "Member Function Callback " + s );
}
void Run()
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback(
&ClassThatProvidesCallback::MemberFunction );
theClassThatUsesCallback->Run();
}
};
I get this error
error C3374: can't take address of 'ClassThatProvidesCallback::MemberFunction'
unless creating delegate instance
When I research this, I find numerous explanations of how to call un-managed code from managed code ( and vice-versa ) I do not need to do this - all the code involved is managed. So I am hoping that someone can point me to a simple way to this.
This is full solution:
ref class ClassThatUsesCallback
{
public:
void setCallback( Action<String^>^ callback )
{
myCallback = callback;
}
void Run()
{
if( myCallback != nullptr ) {
myCallback("This is a test");
}
}
private:
Action<String^>^ myCallback;
};
ref class ClassThatProvidesCallback
{
public:
void MemberFunction( String^ s )
{
Console::WriteLine( "Member Function Callback " + s );
}
void Run()
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback(gcnew Action<String^>(this,
&ClassThatProvidesCallback::MemberFunction));
theClassThatUsesCallback->Run();
}
};
int main(array<System::String ^> ^args)
{
ClassThatProvidesCallback^ c = gcnew ClassThatProvidesCallback();
c->Run();
return 0;
}
Native C++ style typedef is replaced with .NET Action delegate. Additional parameter this is added to setCallback call, it is required to define the class instance which contains the callback function.

C++/CLI marshaling .NET delegate to native delegate

I am trying to pass a delegate with managed parameters to native code to be invoked. My code below runs ok, but the string output is garbage.
Native Class
Header
#pragma once
typedef void (* SegmentCreatedDelegate)(char** arg);
public class SampleClass
{
public:
SampleClass(void);
~SampleClass(void);
void DoWork(SegmentCreatedDelegate callback);
};
Code
SampleClass::SampleClass(void)
{
}
SampleClass::~SampleClass(void)
{
}
void SampleClass::DoWork(SegmentCreatedDelegate callback)
{
for(int x = 0; x< 10; x++)
{
char* myStr2 = "newsegment!";
callback(&myStr2);
}
}
Managed Class
Header
#pragma once
public ref class SampleClassNet
{
public:
delegate void SegmentCreatedDelegateNet(System::String^ arg);
SampleClassNet(void);
void DoWork(SegmentCreatedDelegateNet^ segmentCreatedCallback);
};
Code
SampleClassNet::SampleClassNet(void)
{
}
void SampleClassNet::DoWork(SegmentCreatedDelegateNet^ segmentCreatedCallback)
{
SampleClass* nativeClass = new SampleClass();
System::IntPtr pointer = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(segmentCreatedCallback);
nativeClass->DoWork((SegmentCreatedDelegate)(void*)pointer);
System::GC::KeepAlive(segmentCreatedCallback);
}
This code runs fine with the follow c#.
var sampleClass = new SampleClassNet();
sampleClass.DoWork((Console.WriteLine));
Except I get the following output, instead of the expected 10 entries of "newsegment!".
(ÇÆX
(ÇÆX☺
(ÇÆX☻
(ÇÆX♥
(ÇÆX♦
(ÇÆX♣
(ÇÆX♠
(ÇÆX
(ÇÆX
(ÇÆX
Not exactly "newsegment!", but I am not sure why the marshaling is not working. Maybe I need I need some kind of "MarshalAs" attribute so that the System::String knows that I have 8-bit chars?
As mentioned in the comments, you should convert the char** to a String^. (Btw, why pass char**, not char*? String has a constructer taking char*, which might simplify things a lot.)
I haven't tried the following, but you might give it a try:
public ref class SampleClassNet {
private:
delegate void SegmentCreatedDelegateNative(char** str);
SegmentCreatedDelegateNet^ managedCallback;
SegmentCreatedDelegateNative^ nativeCallback;
void printString(char** string);
public:
delegate void SegmentCreatedDelegateNet(System::String^ arg);
SampleClassNet();
void DoWork(SegmentCreatedDelegateNet^ segmentCreatedCallback);
};
SampleClassNet::SampleClassNet() {
nativeCallback = printString;
}
void SampleClassNet::DoWork(SegmentCreatedDelegateNet^ segmentCreatedCallback) {
SampleClass* nativeClass = new SampleClass();
managedCallback = segmentCreatedCallback;
System::IntPtr pointer = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(nativeCallback);
nativeClass->DoWork((SegmentCreatedDelegate)(void*)pointer);
}
void SampleClassNet::printString(char** string) {
if (this->managedCallback != nullptr) {
String^ str = gcnew String(*string);
managedCallback(str);
}
}
The basic idea is to use another delegate, SegmentCreatedDelegateNative, handed to the native class, and to call the actual managed delegate from the function associated with the wrapper.

Resources