QString to double - qt

void setNewValue(const QString& fhStr)
{
bool ok(false);
double d = fhStr.toDouble(&ok);
if (ok) {
m_newValue = d;
}
}
Passing "23" as fhStr; ok is always evaluating as false i.e., the converted value (d) is never being assigned to the m_newValue
Anything wrong here? Using cross-compiler to run on the ARM board.

http://doc.qt.io/qt-5/qstring.html#toDouble
You probably have some extra info in your string. Use qDebug() to see what is going on:
#include <QDebug>
// ...
void setNewValue(const QString& fhStr)
{
bool ok(false);
double d = fhStr.toDouble(&ok);
if (ok) {
m_newValue = d;
}
qDebug() << fhStr << ok << m_newValue;
}
If you have other information you want to remove from your string, use a QRegularExpression or .strip() or some other string operators to get just the number out.
http://doc.qt.io/qt-5/qregularexpression.html#details
Also look at QValidators.
http://doc.qt.io/qt-5/qvalidator.html#details
http://doc.qt.io/qt-5/qtwidgets-widgets-lineedits-example.html
Hope that helps.

Related

Using requests to verify command success

Lets say Typed Actor A needs to command Typed Actor B to do something. Actor A also needs to know if the command ran succesfully or not but does not want to block operation until this response arrives. My current working theory is that this is best satisfied with Requests. More specifically request(...).then
There is a nice example called "request.cpp" that I have been playing with. My challenge is that I don't really need actor B to return any data. I just need to know if the command was successful or not and if not what error was thrown.
So my question is two fold: 1) Am I correct in thinking that request(...).then is the correct mechanism to do what I want and 2) if so then can a request handle a response that has no data?
This is what I'm trying:
#include <chrono>
#include <cstdint>
#include <iostream>
#include <vector>
#include "caf/all.hpp"
using std::endl;
using std::vector;
using std::chrono::seconds;
using namespace caf;
using cell
= typed_actor<result<void>(get_atom, int32_t)>;
struct cell_state {
static constexpr inline const char* name = "cell";
cell::pointer self;
cell_state(cell::pointer ptr) : self(ptr) {}
cell_state(const cell_state&) = delete;
cell_state& operator=(const cell_state&) = delete;
cell::behavior_type make_behavior() {
return {
[=](get_atom, int32_t input) -> result<void> {
if (input != 5) { // Simulate command successful or not
return; // If successful, then return;
}
else {
return sec::unexpected_message; // If not then return error.
}
},
};
}
};
using cell_impl = cell::stateful_impl<cell_state>;
void multiplexed_testee(event_based_actor* self, vector<cell> cells) {
for (cell& x : cells) {
aout(self) << "cell #" << x.id() << " calling" << endl;
self->request(x, seconds(1), get_atom_v, static_cast<int32_t>(x.id()))
.then(
[=](void) {
aout(self) << "cell #" << x.id() << " -> " << "success" << endl;
},
[=](error& err) {
aout(self) << "cell #" << x.id() << " -> " << to_string(err) << endl;
});
}
}
void caf_main(actor_system& system) {
vector<cell> cells;
for (int32_t i = 0; i < 5; ++i)
cells.emplace_back(system.spawn<cell_impl>());
scoped_actor self{ system };
auto x2 = self->spawn(multiplexed_testee, cells);
self->wait_for(x2);
}
CAF_MAIN()
When I compile, I get an error on the empty return statement saying "return-statement with no value, in function returning caf::result<void>. Is there a better way to do this?
My backup plan is to change my command definition to just return a standard error and return sec::none if the operation was successful. But I'm afraid that approach violates the spirit of the whole optional-second-parameter for error conditions. How well am I thinking about all this?
Is there a better way to do this?
You had the right idea. The result<void> expects either an error or a 'void' value. Since void{} isn't a thing in C++, you can do return caf::unit; to tell result<void> to construct an "empty" result. On the receiver's side, you already did the right thing: then with a lambda taking no arguments.
Minor point:
[=](void) { ... }
This is a C-ism from the early days where the compiler allowed you to do silly things. Just drop the void, it serves no purpose. :)

Declaring a shared Pointer within a function produce a leaky memory behavior

I‘ve been trying to understand smart pointers, and as I understood, smart pointer will destroy themselves once they are not reachable through the code.
For this reason I was trying to implement a demonstration for this behavior:
#include<iostream>
#include<memory>
using namespace std;
void shared(){
cout<<"Shared Pointer:"<<endl;
shared_ptr<int> number = make_shared<int>(50);
cout<<*number<<endl;
cout<<number<<endl;
}
int main(){
int address;
shared();
cout<<"please enter the targeted address:"<<endl;
cin>>address;
int *pointer = (int *) address;
cout<<"we found this number: "<<*pointer<<endl;
}
output:
Shared Pointer:
50
0xf28c30
please enter the targeted address:
15895600 // I just converted the hexdecimal above to decimal number.
we found this number: 50
So I‘m able to retrieve the value 50 from outside the function shared(), by manually entering its address in the console.
Isn‘t supposed to be null or random number? If this is normal then how smartpointers are made to avoid memory leaks!?
P.S: doing the same test using a normal pointer will produce the same results unless we add delete pointer; (which is the expected behavior)
I appreciate any idea about this specific behavior.
To make sure that the memory was deleted it is better to test the smart pointers with a class
class Greeting {
public:
Greeting()
{
std::cout << "Hello" << std::endl;
}
~Greeting()
{
std::cout << "Bye" << std::endl;
}
};
void shared() {
shared_ptr<Greeting> var = make_shared<Greeting>();
}
int main() {
std::cout << "Start" << std::endl;
shared();
std::cout << "End" << std::endl;
}
You will get the following output:
Start //Start of the main
Hello // When creating the object (the resource)
Bye // **When destructing the object (the resource)**
End //End the main

Address of a member data stored on heap memory

I'm learning C++ and I've got a question, about the material that I'm using. I think that there may be some errors in editing, but I'm quite not sure. My book's name is "C++ through game programming".
Here's the code in the book, it's in chapter 9.
class Critter {
public:
Critter(const string &name = "", int age = 0);
~Critter();
Critter(const Critter &c);
Critter& operator=(const Critter& c);
void greet() const;
private:
string *mName;
int mAge;
};
Critter::Critter(const string &name, int age) {
cout << "Constructor called\n";
mName = new string(name);
mAge = age;
}
Critter::~Critter() {
cout << "Destructor called\n";
delete mName;
}
Critter::Critter(const Critter &c) {
cout << "Copy constructor called\n";
mName = new string(*(c.mName));
mAge = c.mAge;
}
Critter& Critter::operator=(const Critter& c) {
cout << "Overloading assignment operator called\n";
if (this != &c) {
delete mName;
mName = new string(*(c.mName));
mAge = c.mAge;
}
return *this;
}
void Critter::greet() const {
cout << "I'm " << *mName << " and I'm " << mAge << " years old.\n";
cout << "&mName: " << &mName << endl;
}
Here I'm creating a Critter class, and test for allocate heap memory. As you can see, I declared a pointer *mName that point to a string object on the heap memory.
So what is confusing me now is that, in the last method:
void Critter::greet() const
They say that "the address of the string on the heap stored in the pointer m_pName" is &mName, as they print it out in the method.
But I think that mName itself is the address of the string object stored on the heap. So &mName is the address of the pointer itself.
To make it clear, I try to print &mAge also.
And what I got is:
&mName: 0x7fff5fbff640
mName: 0x100103b20
&mAge: 0x7fff5fbff648
As you can see, &mName and &mAge have nearly similar address, but mName's is different. So maybe mName points to the heap, and &mName and &mAge are actually the addresses that belong to the stack.
That's what I think, I tried to find the errata of that book but I found nothing. Can you guys make it clear for me. Was I right or might I have some misunderstanding.
Thanks for your help. I really appreciate it.
You do have it right. Because mName is a pointer, the value of that pointer is the address of the string object that it points to. &mName is the address where the pointer itself is stored.

How to get human-readable event type from QEvent?

I want to debug event handling code and would like to convert QEvent::Type enum's value to a human-readable string. QEvent has a Q_GADGET macro, so presumably there's a way of pulling that off?
Recent versions of Qt do the right thing when outputting events to the debug stream, so the below isn't neccessary. If you get an error similar to warning C4273: 'operator <<' : inconsistent dll linkage, it means that your version of Qt already supports this without need for the code below.
The Q_GADGET macro adds a QMetaObject staticMetaObject member to the class. The static metaobject's definition is generated by moc, and it - in the case of QEvent - contains the enumeration information.
Below is an example of how to leverage that to give a more reasonable QDebug output of events.
#include <QEvent>
#include <QMetaEnum>
#include <QDebug>
/// Gives human-readable event type information.
QDebug operator<<(QDebug str, const QEvent * ev) {
static int eventEnumIndex = QEvent::staticMetaObject
.indexOfEnumerator("Type");
str << "QEvent";
if (ev) {
QString name = QEvent::staticMetaObject
.enumerator(eventEnumIndex).valueToKey(ev->type());
if (!name.isEmpty()) str << name; else str << ev->type();
} else {
str << (void*)ev;
}
return str.maybeSpace();
}
Use example:
void MyObject::event(QEvent* ev) {
qDebug() << "handling an event" << ev;
}
Q_GADGET and Q_ENUM can be combined to get the following template:
template<typename EnumType>
QString ToString(const EnumType& enumValue)
{
const char* enumName = qt_getEnumName(enumValue);
const QMetaObject* metaObject = qt_getEnumMetaObject(enumValue);
if (metaObject)
{
const int enumIndex = metaObject->indexOfEnumerator(enumName);
return QString("%1::%2::%3").arg(metaObject->className(), enumName, metaObject->enumerator(enumIndex).valueToKey(enumValue));
}
return QString("%1::%2").arg(enumName).arg(static_cast<int>(enumValue));
}
Example:
void MyObject::event(QEvent* ev)
{
qDebug() << ToString(ev->type());
}

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Car' (or there is no acceptable conversion)

Queue class
#ifndef Queue_H
#define Queue_H
#include "Car.h"
#include <iostream>
#include <string>
using namespace std;
const int Q_MAX_SIZE = 20;
class Queue {
private:
int size; // size of the queue
Car carQueue[Q_MAX_SIZE];
int front, rear;
public:
Queue();
~Queue();
bool isEmpty();
bool isFull();
void enqueue(Car c);
void dequeue(); // just dequeue the last car in the queue
void dequeue(Car c); // if a certain car wants to go out of the queue midway.
// Condition: Car is not in washing. Meaning is not the 1st item in the queue
void dequeue(int index); // same as the previous comment
Car getFront();
void getCarQueue(Queue);
int length();
Car get(int);
};
Queue::Queue() {
size = 0;
front = 0;
rear = Q_MAX_SIZE -1;
}
Queue::~Queue() {
while(!isEmpty()) {
dequeue();
}
}
void Queue::enqueue(Car c) {
if (!isFull()) {
rear = (rear + 1) % Q_MAX_SIZE; // circular array
carQueue[rear] = c;
size++;
} else {
cout << "Queue is currently full.\n";
}
}
void Queue::dequeue() {
}
void Queue::dequeue(int index) {
if(!isEmpty()) {
front = (front + 1) % Q_MAX_SIZE;
if(front != index) {
carQueue[index-1] = carQueue[index];
rear--;
size--;
} else {
cout << "Not allowed to dequeue the first car in the queue.\n";
}
} else {
cout << "There are no cars to dequeue.\n";
}
}
bool Queue::isEmpty() {
return size == 0;
}
bool Queue::isFull() {
return (size == Q_MAX_SIZE);
}
Car Queue::getFront() {
return carQueue[front];
}
int Queue::length() {
return size;
}
Car Queue::get(int index) {
return carQueue[index-1];
}
void Queue::getCarQueue(Queue q) {
for(int i = 0; i< q.length(); i++)
cout << q.get(i) << endl; // Error here
}
#endif
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Car' (or there is no acceptable conversion)
I get this error which is kind of odd. so is there anything wrong? Thanks!
cout has no idea how to process a car object; it has never seen a car object and doesn't know how you output a car as text. cout can only process types it knows about, string, char, int, etc. The specific error is because there is version of operator << that takes an ostream and a car.
There are two options:
Creation an overload for operator<< that takes an ostream and a car. That will show cout how to output a car. This isn't usually done becuase there is usually more than one way your would want to display a car.
Write the output statement so that it manually prints out car properties like
cout << c.getMake() << " " << c.getModel()

Resources