Error: C2280 Creating a vector of unique_ptr to Class - pointers

It seems that when using a unique_ptr in vector<unique_ptr<UserInterface>> I get an error stating:
Error 1 error C2280: 'std::unique_ptr<UserInterface,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function c:\pr...ude\xmemory0 593 1 Win32Project1
Seemingly, no configuration allows me to store [smart] pointers to the UserInterface class, which has a simple structure:
#define InterfaceContruct vector<unique_ptr<UserInterface>>
class UserInterfaceMgmt
{
public:
UserInterfaceMgmt();
~UserInterfaceMgmt();
InterfaceContruct Interface;
void AddUIElement();
void RemoveUIElement();
void DrawInterface();
void MoveElement();
private:
};
Even if no function is called, the error shows up (InterfaceContruct Interface; is instantiated) I tried putting the copy constructor in private but it persists.
The .cpp file is:
#include "stdafx.h"
#include "UserInterfaceMgmt.h"
UserInterfaceMgmt::UserInterfaceMgmt()
{
}
UserInterfaceMgmt::~UserInterfaceMgmt()
{
}
void UserInterfaceMgmt::DrawInterface(){
for (UINT i = 0; i < Interface.size(); i++)
{
Interface[i]->Draw();
}
}

std::vector (and most other containers in std::) require the value type to be copy-constructible. std::unique_ptr isn't copy constructible. Use std::shared_ptr or any other copy constructible types / pointers.
The clue is to look for attempting to reference a deleted function. This means there is some method which = delete has been used with. For instance:
struct Foo
{
Foo(const Foo & rhs) = delete; // A deleted function
}

Related

Segmentation Faults when testing typed actors with custom atoms

I am trying to use the testing macros with my actors but I am getting a lot of segmentation faults. I believe I have narrowed down the problem to my use of custom atoms. To demonstrate the issue I modified the 'simple actor test' from here to make the adder strongly typed.
#include "caf/test/dsl.hpp"
#include "caf/test/unit_test_impl.hpp"
#include "caf/all.hpp"
namespace {
struct fixture {
caf::actor_system_config cfg;
caf::actor_system sys;
caf::scoped_actor self;
fixture() : sys(cfg), self(sys) {
// nop
}
};
using calculator_type = caf::typed_actor<caf::result<int>(int, int)>;
calculator_type::behavior_type adder() {
return {
[=](int x, int y) {
return x + y;
}
};
}
} // namespace
CAF_TEST_FIXTURE_SCOPE(actor_tests, fixture)
CAF_TEST(simple actor test) {
// Our Actor-Under-Test.
auto aut = self->spawn(adder);
self->request(aut, caf::infinite, 3, 4).receive(
[=](int r) {
CAF_CHECK(r == 7);
},
[&](caf::error& err) {
// Must not happen, stop test.
CAF_FAIL(err);
});
}
CAF_TEST_FIXTURE_SCOPE_END()
This works great. I then took it one step further to add a custom atom called "add_numbers"
#include "caf/test/dsl.hpp"
#include "caf/test/unit_test_impl.hpp"
#include "caf/all.hpp"
CAF_BEGIN_TYPE_ID_BLOCK(calc_msgs, first_custom_type_id)
CAF_ADD_ATOM(calc_msgs, add_numbers)
CAF_END_TYPE_ID_BLOCK(calc_msgs)
namespace {
struct fixture {
caf::actor_system_config cfg;
caf::actor_system sys;
caf::scoped_actor self;
fixture() : sys(cfg), self(sys) {
// nop
}
};
using calculator_type = caf::typed_actor<caf::result<int>(add_numbers, int, int)>;
calculator_type::behavior_type adder() {
return {
[=](add_numbers, int x, int y) {
return x + y;
}
};
}
} // namespace
CAF_TEST_FIXTURE_SCOPE(actor_tests, fixture)
CAF_TEST(simple actor test) {
// Our Actor-Under-Test.
auto aut = self->spawn(adder);
self->request(aut, caf::infinite, add_numbers_v, 3, 4).receive(
[=](int r) {
CAF_CHECK(r == 7);
},
[&](caf::error& err) {
// Must not happen, stop test.
CAF_FAIL(err);
});
}
CAF_TEST_FIXTURE_SCOPE_END()
This compiles fine but produces a segmentation fault at runtime. I suspect it has something to do with the fact that I am not passing calc_msgs to anything. How do I do that? Or is something else going on?
The ID block adds the compile-time meta data. But you also need to initialize some run-time state via
init_global_meta_objects<caf::id_block::calc_msgs>();
Ideally, you initialize this state before calling any other CAF function. In particular before initializing the actor system. CAF itself uses custom main functions for its test suites to do that (cf. core-test.cpp). In your case, it would look somewhat like this:
int main(int argc, char** argv) {
using namespace caf;
init_global_meta_objects<id_block::calc_msgs>();
core::init_global_meta_objects();
return test::main(argc, argv);
}
This probably means that you would need to put the type ID block into a header file. This is nothing special about the unit tests, though. If you run a regular CAF application, you need to initialize the global meta objects as well. CAF_MAIN can do that for you as long as you pass it the type ID block(s) or you need to call the functions by hand. The CAF manual covers this in a bit more detail here: https://actor-framework.readthedocs.io/en/0.18.5/ConfiguringActorApplications.html#configuring-actor-applications.
If this is your only test at the moment, you can define CAF_TEST_NO_MAIN before including caf/test/unit_test_impl.hpp and then add the custom main function. Once you have multiple test suites, it makes sense to move the main to its own file, though.

Why std::vector of pointers avoid deconstruction bugs?

In one of my project I managed to fix a bug switching from a std::vector of objects to a std::vector of pointers to the object. Using the debugger I found that the error occurred when I was calling the std::vector<T,Allocator>::clear that it is supposed to destroy the objects stored in the vector. I am happy I solved the issue but I would like to know why I was able to!
Here I attach the code incriminated:
#include <vector>
#include <memory>
#include <string>
class Base
{
public:
Base(int a);
Base(const Base& o)=default;
Base& operator=(const Base& o)=default;
Base(Base&& o)=default;
Base& operator=(Base&& o)=default;
virtual ~Base()=default;
virtual void Do();
};
class Derived: public Base
{
private:
std::string b;
public:
Derived(int a, std::string& b) : Base(a), b(b) {}
};
//Other derived classes from Base overriding Do
class Main{
private:
std::vector<Derived> v;
public:
Main();
void Do(int i, std::string& b){
/*
if something happens
v.emplace_back(a, b);// push_back equivalently for our purpose
if something else happens
v.erase(iterator)
*/
}
void reset(){
v.clear();
}
};
class Main1{
private:
std::vector<std::unique_ptr<Derived>> v;
public:
Main1();
void Do(int i, std::string& b){
/*
if something happens
v.push_back(std::unique_ptr<Derived>(new Derived(i, b)));
if something else happens
v.erase(iterator)
*/
}
void reset(){
v.clear();
}
};
int main()
{
Main m;
for(int i=0; i<101; ++i){
//something
m.Do(i, b);
//something
if(i%10==0)
m.reset(); //The bug is here. If I use Main1 everything runs smoothly
}
return 0;
}
This is a simplified version of the code that creates me problem. I hope that the detail are enough to give the correct contest for the answer.
The debugger points me deep in the code defining what a deconstructor does reporting a segmentation fault, and personally I cannot understand what that code does.
The compiler I am using is g++ 10.1 with the std=c++17 flag.

Qt tr() translation with static members and namespaces

I'm working on translation our Qt GUI project.
*.ts file is generated successfully.
I filled *.ts file with translations using Qt Linguist.
But at runtime, translation with namespaces and static members does not work.
Other translations (when tr() method calls in class, that are inherited from QObject) works ok.
I have the following code (translation does not work):
Example with namespaces:
// example with namespaces
// declaration in header
namespace Error
{
namespace RadionetworkInput
{
QString alreadyInUse = QT_TR_NOOP("already in use");
char requestFailed[] = QT_TR_NOOP("request failed");
}
}
Usage in cpp:
// usage in cpp code0
QString error0 = Error::RadionetworkInput::alreadyInUse;
QString error1 = tr(Error::RadionetworkInput::requestFailed);
Example with static members:
// example with static members
// declaration in header
namespace Error
{
class RadionetworkInput
{
public:
static const QString alreadyInUse;
static const char requestFailed[];
}
QString Error::RadionetworkInput::alreadyInUse = QT_TR_NOOP("already in use");
char Error::RadionetworkInput::requestFailed[] = QT_TR_NOOP("request failed");
}
Usage in cpp code
// usage in cpp code
QString error0 = Error::RadionetworkInput::alreadyInUse;
QString error1 = tr(Error::RadionetworkInput::requestFailed);
Example, with working translation:
class ViewNetwork : public QObject
{
Q_OBJECT
public:
explicit ViewNetwork(QString name = tr("New Radionetwork"));
};
Usage in code:
ViewNetwork::ViewNetwork(QString name)
{
QString dummy = name;
}
Using QObject::tr() instead QT_TR_NOOP() macro does not help.
Problem is your understanding how it works. With static members variables they are initialized before main function starts.
This means two thing:
they are initialized before QApplication object is created and before yuo load translation files! (I'm surprised that this didn't lead to a crash)
value is calculated only once (not updated if translation changes)!
What you should do? Just change static variable to functions:
// example with namespaces
// declaration in header
namespace Error
{
namespace RadionetworkInput
{
QString alreadyInUse() { return QT_TR_NOOP("already in use"); }
QString requestFailed() { return QT_TR_NOOP("request failed"); }
}
}
and
// example with static members
// declaration in header
namespace Error
{
class RadionetworkInput
{
public:
static QString alreadyInUse();
static QString requestFailed();
}
QString Error::RadionetworkInput::alreadyInUse() { return QT_TR_NOOP("already in use"); }
QString Error::RadionetworkInput::requestFailed() { return QT_TR_NOOP("request failed"); }
}
Returning translation as char[] is pointless, co I've corrected that also (I don't know why you did it).

Can't use attachInterrupt in a library

I'm writing a simple library for an ultrasonic distance sensor and thought i'd try using interrupts.
However i can't set my functions in the attachCallback method properly.
I want HCSR04Interrupt::echoHigh() and HCSR04Interrupt::echoLow() called when the pin goes high and low respectively.
I've Googled this to no avail. The Ardiuno IDE says the following:
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::getDistance()':
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:31: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()'
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::echoHigh()':
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:47: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()'
Here is my header:
#ifndef _HCSR04Interrupt_
#define _HCSR04Interrupt_
#include "Arduino.h"
#define HCSR04_CM_FACTOR 58.0
#define HCSR04_IN_FACTOR 148.0
#define HCSR04_CM_MODE 0
#define HCSR04_IN_MODE 1
class HCSR04Interrupt {
public:
double distance;
HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)());
void setUnits(int units);
void getDistance();
private:
int _trigger_pin;
int _echo_pin;
int _units;
unsigned long _micros_start;
void (*_callback)();
void initialize();
void echoHigh();
void echoLow();
};
#endif
And my implementation (not complete since i cant get past the attachInterrupt step):
#include "Arduino.h"
#include "HCSR04Interrupt.h"
HCSR04Interrupt::HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)()) {
_trigger_pin = trigger_pin;
_echo_pin = echo_pin;
_callback = callback;
initialize();
}
void HCSR04Interrupt::setUnits(int units) {
_units = units;
}
void HCSR04Interrupt::initialize() {
pinMode(_trigger_pin, OUTPUT);
pinMode(_echo_pin, INPUT);
digitalWrite(_trigger_pin, LOW);
}
void HCSR04Interrupt::getDistance() {
//Listen for the RISING interrupt
attachInterrupt(_echo_pin - 2, echoHigh, RISING);
//The trigger pin should be pulled high,
digitalWrite(_trigger_pin, HIGH);
//for 10 us.
delayMicroseconds(20);
//Then reset it.
digitalWrite(_trigger_pin, LOW);
}
void HCSR04Interrupt::echoHigh() {
_micros_start = micros();
detachInterrupt(_echo_pin - 2);
attachInterrupt(_echo_pin - 2, echoLow, FALLING);
}
void HCSR04Interrupt::echoLow() {
detachInterrupt(_echo_pin - 2);
unsigned long us = micros() - _micros_start;
distance = us;
(*_callback)();
}
So the compiler (not the IDE) tells you exactly what's wrong:
argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()
So, while attachInterrupt() takes a function pointer of type void (*)(), you're trying to pass it a non-static member function, which you can't. You can try making the member function static and casting:
static void echoHigh();
// ...
attachInterrupt(_echo_pin - 2, reinterpret_cast<void (*)()>(&echoHigh), RISING);
Arduino interrupt handlers can only be functions. You are trying make method of an object an interrupt handler. Hence the compiler complains.
To be more precise about it, object methods are like functions, but it is as if they take a "hidden" parameter, which specifies the object instance. Therefore, they actually have different type signatures from plain functions. This disallows one to pass a method pointer when what a function is looking for is a plain function pointer.
The solution is to move your echoHigh() and echoLow() out of the HCSR04Interrupt class, and make them plain functions.
As I stumbled upon this question and it hasn't had an accepted answer, I write what I found, which worked for me:
The interrupt has to be called by a global wrapper. This wrapper needs to call a handleInterupt function of the class. Therefore it has to know the class. This can be done by storing it in a global variable. If multiple instances of the class should be used, multiple such global variables have to be used. But as the interrupt pins are just a few you can write a global variable and function for every pin:
MyClass theInstance_pin3 = NULL;
MyClass theInstance_pin7 = NULL;
// Somewhere, fill in an initialized copy of MyClass,
// and set theInstance_pin3 or theInstance_pin7 to it
void ISR_3()
{
if (theInstance_pin3)
theInstance_pin3->handleInterrupt();
}
void ISR_7()
{
if (theInstance_pin7)
theInstance_pin7->handleInterrupt();
}
as a reference see: http://forum.arduino.cc/index.php?topic=41713.0
or http://forum.arduino.cc/index.php?topic=160101.0
I got around this by making a singleton base class which represents the hardware as a whole (which kinda makes sense in this situation anyway).
Any function pointers can then be passed to the sub-component class, and handled by the singleton, whose member variables and methods are all static.
Example headers (untested):
// Sub-component
class LampButton {
public:
LampButton(int pin, void(*pushHandler)());
}
// Sub-component
class LampLed {
public:
LampLed(int pin);
void toggle();
}
// Singleton represents the hardware in it's entirety
class Lamp {
public:
// Call this instead of a constructor
static void initialize(int buttonPin, int ledPin);
// Function implemented inline for clarity - don't do this
static void handleButtonPush() {
led.toggle();
}
private:
static LampButton button;
static LampLed led;
}

QObject retunrs with exception even after the copy constructor being declared

I am trying to write a sample code for qt script. I thought I am doing the right thing when I declare the QObjecy with the copy construtor and I also took the liberty to declare the = operator. But this code keeps giving me the
'QObject::QObject' : cannot access private member declared in class 'QObject'
Error.
I am declaring a MyClass which is a QObject as follows. I am aware of the fact that this can some one see what I am doing a wroing here.
The header:
#ifndef SCRIPT_CLASSES_H
#define SCRIPT_CLASSES_H
#include "QObject"
#include "QtScript/QScriptValue"
#include "QtScript/QScriptable"
#include "QtScript/QScriptClass"
class MyClass : public QObject
{
Q_OBJECT
// Q_PROPERTY( int _id WRITE setId READ id )
public :
MyClass(QObject *aparent =0) ;
~MyClass();
// bool operator =(MyClass obj);
public slots:
void setId(int d);
int id() const ;
// bool MyClass::equals(const MyClass &other);
private :
int _id;
};
class QScriptEngine;
class Script_Classes : public QObject, public QScriptClass
{
public:
Script_Classes(QScriptEngine *engine);
~Script_Classes();
private :
static QScriptValue myClassToScript(QScriptEngine *engine,const MyClass &in);
static void myClassFromScript(const QScriptValue &object, MyClass &out);
};
#endif // SCRIPT_CLASSES_H
And my source class is as follows:
#include "script_classes.h"
#include "QMetaType"
#include "QtScript/QScriptEngine"
#include "QtScript/QScriptValue"
Q_DECLARE_METATYPE(MyClass)
Q_DECLARE_METATYPE(MyClass*)
MyClass::MyClass(QObject *aparent) : QObject (aparent){}
MyClass::~MyClass(){}
void MyClass::setId(int d){
_id = d;
}
int MyClass::id() const{
return _id;
}
bool MyClass::equals(const MyClass &other)
{
return id() == other.id();
}
bool MyClass::operator =(MyClass obj){
return id()==obj.id();
}
Script_Classes::Script_Classes(QScriptEngine *engine):QObject(engine),QScriptClass(engine)
{
qScriptRegisterMetaType<MyClass>(engine, myClassToScript, myClassFromScript);
MyClass testClass(this);
}
void Script_Classes::myClassFromScript(const QScriptValue &object, MyClass &out){
out.setId(object.property("id").toInt32());
}
QScriptValue Script_Classes::myClassToScript(QScriptEngine *engine, const MyClass &in)
{
QScriptValue value = engine->newObject();
value.setProperty("id", in.id());
return value;
}
The problem is that you cannot copy a QObject. From the QObject documentation:
QObject has neither a copy constructor nor an assignment operator.
This is by design. Actually, they are declared, but in a private
section with the macro Q_DISABLE_COPY(). In fact, all Qt classes
derived from QObject (direct or indirect) use this macro to declare
their copy constructor and assignment operator to be private. The
reasoning is found in the discussion on Identity vs Value on the Qt
Object Model page.
The main consequence is that you should use pointers to QObject (or to
your QObject subclass) where you might otherwise be tempted to use
your QObject subclass as a value. For example, without a copy
constructor, you can't use a subclass of QObject as the value to be
stored in one of the container classes. You must store pointers.
Also QObject has not the == implemented so you cannot compare two instance of your class.
PS What is the point of overloading the = operator and making it operate like the == one? This makes your code obfuscated and debugging much more complex.
EDIT
Assume you have the following simple class inheriting from QObject
class A : public QObject
{
Q_OBJECT
public:
int anInt;
double aDouble;
}
Assume now that you want to create two inctances of A somewhere in your code.
A a1;
A a2;
It is illegal to call a1=a2 since QObject's = operator is not public. What you need to do in order to achieve the copying of the data is to do it manually :
a2.anInt = a1.anInt
a2.aDouble = a1.aDouble
On the other hand if you used pointers it is totally legal to point at the same object
A* a1 = new A;
A* a2 = new A;
a1 = a2;
Now both a1 and a2 point at the same memory location and have the same data. If you want to have two different objects you could create a constructor with argument a pointer to the object. For our simple class you could have:
A::A(A* a)
{
anInt = a->anInt;
aDouble = a->aDouble;
}
and now it is legal do:
A a1;
A a2(&a1);
If you wonder why QObject does not allow assignment read the Identity vs Value part of the Object Model documentation.

Resources