I just insert pValue to map next i get it from map ,and its value should be 20 ,but not, why?
typedef shared_ptr<BaseObject> PtrValue;
class CodeExecuteContext{
public:
map<string,PtrValue> varIdentPool;
};
class BaseInteger :public BaseObject{
public:
int value;
BaseInteger(int val):value(val){
enumObjType = INT;
};
};
...
PtrValue pValue = rightNode->executeCode(context);
context.varIdentPool.insert(make_pair(leftNode.idName,pValue));
BaseInteger * baseInteger = (BaseInteger *) pValue.get();
cout << "==AssignmentASTFork== insert [ " << leftNode.idName << " , " << baseInteger->value << " ]" <<endl;
map<string,PtrValue>::iterator it;
for (it = context.varIdentPool.begin() ; it!=context.varIdentPool.end();it++) {
BaseInteger * baseInteger = (BaseInteger *) it->second.get();
cout << "[key : " << it->first << ", value : " << baseInteger->value << endl;
}
result:
==AssignmentASTFork== insert [ arg , 20 ]
[key : arg, value : 32742]
The map::insert function returns "pair", where the boolean from the pair indicates whether the element has been inserted or not. If the boolean is true, it has been inserted. If the key already existed, the boolean will be false and the key-value pair has not been inserted.
Try "auto insertResult = context.varIdentPool.insert(make_pair(leftNode.idName,pValue));"
If insertResult.second == false, the key already existed.
The iterator (insertResult.first) will always point to the item from the map.
With that iterator you can alter the value from the map by "insertResult.first->second = newValue"
Related
I have this code:
int do_transact(ifstream & inFile, list<shared_ptr<Bike>> bikelist, status s)
{
int id, i = 0, size = bikelist.size();
float days;
string str, str2;
char name[50];
list<shared_ptr<Bike>>::iterator it = bikelist.begin();
if (s == NO_STATUS) //performs rental
{
inFile >> id;
inFile >> days;
inFile >> str;
inFile >> str2;
strcpy_s(name, str.c_str());
while (i < size)
{
if (id == (*it)->id_num) // rents bike
{
cout << "vvvvvv PERFORMING RENTAL vvvvvv" << endl << endl;
cout << "The price of this rental will be: $" << (days)*((*it)->cost_per_day) << endl;
strcpy_s((*it)->to_whom, name);
(*it)->rented_code = RENTED;
cout << "Thank you for your business!" << endl << endl;
return 0;
}
i++;
it++;
}
}
}
I am trying to change to_whom and rented_code in the original list, but it is not updating.
What is the syntax I need in order to change these values the way I need?
I made a small reproducible example:
#include <Rcpp.h>
using namespace Rcpp;
class Index {
public:
Index(int i_) : i(i_) {}
int getI() { return i; }
private:
int i;
};
// [[Rcpp::export]]
SEXP getXPtrIndex(int i) {
Rcout << "getXPtrIndex: i = " << i << std::endl;
Index ind(i);
Rcout << "getXPtrIndex: ind.i = " << ind.getI() << std::endl;
return XPtr<Index>(&ind, true);
}
// [[Rcpp::export]]
void getXPtrIndexValue(SEXP ptr) {
XPtr<Index> ind_ptr(ptr);
Rcout << "getXPtrIndexValue: ind_ptr->i = " << ind_ptr->getI() << std::endl;
Index ind = *ind_ptr;
Rcout << "getXPtrIndexValue: ind.i = " << ind.getI() << std::endl;
}
Basically, I define a small class, along with a function to get an external pointer of an element of this class. The last function is used to print the weird accessor when returning the class element back to C++.
Results in R:
> (extptr <- getXPtrIndex(10))
getXPtrIndex: i = 10
getXPtrIndex: ind.i = 10
<pointer: 0x7ffeeec31b00>
> getXPtrIndexValue(extptr)
getXPtrIndexValue: ind_ptr->i = 33696400
getXPtrIndexValue: ind.i = 0
Why can't I access 10?
I'm using Rcpp version 0.12.12 (the latest I think).
It seems to have something to do with the temporary object---by the time your second function runs the "content" of the first is already gone.
So either just make
Index ind(10);
a global, and comment out the line in your first function. Then all is peachy (I changed the R invocation slightly):
R> extptr <- getXPtrIndex(10)
getXPtrIndex: i = 10
getXPtrIndex: ind.i = 10
R> getXPtrIndexValue(extptr)
getXPtrIndexValue: ind_ptr->i = 10
getXPtrIndexValue: ind.i = 10
R>
Or it also works the same way when you make you Index object static to ensure persistence. Corrected example below.
#include <Rcpp.h>
using namespace Rcpp;
class Index {
public:
Index(int i_) : i(i_) {}
int getI() { return i; }
private:
int i;
};
// [[Rcpp::export]]
SEXP getXPtrIndex(int i) {
Rcout << "getXPtrIndex: i = " << i << std::endl;
static Index ind(i);
Rcout << "getXPtrIndex: ind.i = " << ind.getI() << std::endl;
return XPtr<Index>(&ind, true);
}
// [[Rcpp::export]]
void getXPtrIndexValue(SEXP ptr) {
XPtr<Index> ind_ptr(ptr);
Rcout << "getXPtrIndexValue: ind_ptr->i = " << ind_ptr->getI() << std::endl;
Index ind = *ind_ptr;
Rcout << "getXPtrIndexValue: ind.i = " << ind.getI() << std::endl;
}
/*** R
extptr <- getXPtrIndex(10)
getXPtrIndexValue(extptr)
*/
I want to delete items out of my QMultiHash. Looking at the docs, I believe I am doing it correctly but it always crashes after the first delete. What am I doing wrong?
Here is my code:
for (QMultiHash<int, Frame*>::iterator i = m_FrameBuffer.begin(); i != m_FrameBuffer.end(); ++i) {
if ( (frameNumber - i.key()) >= ( 5 ) ) { // Delete frames 5 frames old or more
qDebug() << "DELETE ==> Key:" << i.key() << "Value:" << i.value() << " Difference: " << (frameNumber - i.key());
int removed = m_FrameBuffer.remove(i.key());
qDebug() << "Removed this many: " << removed;
}
}
Here is the output:
FRAME COUNT: 1
FRAME COUNT: 2
FRAME COUNT: 3
FRAME COUNT: 4
FRAME COUNT: 5
DELETE ==> Key: 2 Value: Frame(0x138a400) Difference: 5
Removed this many: 1
The program has unexpectedly finished.
Your iterator becomes invalid after you remove items from a container while iterating it. Try this:
QList<int> keys = m_FrameBuffer.keys();
foreach (int key, keys)
{
int diff = frameNumber - key;
if (diff >= 5)
{
qDebug() << "DELETE ==> Key:" << key
<< "Value:" << m_FrameBuffer.value(key)
<< "Difference: " << diff;
int removed = m_FrameBuffer.remove(key);
qDebug() << "Removed this many: " << removed;
}
}
Also you can use QMutableHashIterator for it:
QMutableHashIterator<int, Frame*> it(m_FrameBuffer);
while (it.hasNext())
{
it.next();
int key = it.key();
int diff = frameNumber - it.key();
if (diff >= 5)
{
qDebug() << "Items to be removed:"
<< m_FrameBuffer.values(it.key()).size();
it.remove();
}
}
Lets say we have a variable called X and we do some operations on it. now for printing it on the QtextEdit I want to print it like this cout on console:
cout << "The value of X is " << X << endl;
But the setText function only prints out a QString not both "the value of ... " and X.
You can use a QTextStream to write data into a QString similar to cout:
int X = 42;
QString str;
QTextStream out(&str);
out << "The value of X is " << X << endl;
qDebug() << str;
Output:
"The value of X is 42
"
I would solve this in the following way:
QString text = QString("This is my value: %1").arg(x); // x can be either number or string
textEdit->setText(text);
If your "x" is an integer, for example, you can convert that number into a string and concatenate that with the introducing string like that:
QString myText = "This is my value: " + QString::number(x);
If x=5 this will give you this string:
This is my value: 5
You can now assign myText to your QTextEdit with settext.
I have a QAbstractItemModel-derived class attached to a QTreeView.
Model implements 2 top-level rows and one of them has 3 sub-rows. Only first 2 sub-rows are displayed. If I add one “dummy” top-level row then everything is displayed.
I used qDebug() to print how many times QTreeView calls my model::data() and with what indexes (only Qt::DisplayRole cases are printed) and see that it is actually called 2 times for sub-rows instead of 3.
Of course, first suspicion is that my model::rowCount() is incorrect and makes QTreeView “think” that there are only 2 sub-rows. So here are qDebug() prints:
rowCount returning 3 for parent 0xbc6f70
…….
Qt::DisplayRole for row 0 ,column 0 pointer 0xbc6fc0 parent= 0xbc6f70
Qt::DisplayRole for row 1 ,column 0 pointer 0xbc7068 parent= 0xbc6f70
where 0xbc6f70 is:
parent.internalPointer() in model::rowCount(const QModelIndex &parent)
index.parent().internalPointer() in model::data(const QModelIndex &index, int role)
So why is model::data() being called for row 0 and row 1 but not for row 2 if model::rowCount() returned 3 for index with internalPointer() 0xbc6f70?
Here is the code:
int Model_Tree::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid())
{
// This is 1st level
qDebug() << "rowCount returning m_RowCount" << m_RowCount << "for !parent.isValid()" << parent.internalPointer() << "row" << parent.row() << "column" << parent.column();
return m_RowCount;
}
int column = parent.column();
if(0 != column)
{
qDebug() << "rowCount returning 0 for parent 0 != column (" << column << ")";
return 0; // only item at 0th column can have children
}
const TreeItem* pTreeItem = (const TreeItem*)parent.internalPointer();
if (0 == pTreeItem)
{
qDebug() << "rowCount returning 0 for parent 0==pTreeItem" << pTreeItem;
return 0;
}
qDebug() << "rowCount returning " << pTreeItem->m_Children.size() << "for parent " << pTreeItem << "type:" << pTreeItem->m_type;
return pTreeItem->m_Children.size();
}
QVariant Model_Tree::data(const QModelIndex &index, int role) const
{
if (!(index.isValid()))
{
return QVariant();
}
switch (role)
{
case Qt::TextAlignmentRole:
return Qt::AlignTop;
case Qt::DisplayRole:
void* p = index.internalPointer();
int column = index.column();
int row = index.row();
qDebug() << "Qt::DisplayRole for row " << row << ",column " << column << "pointer" << p << "parent=" << index.parent().internalPointer();
// .... the rest of Model_Tree::data implementation
}
and here is some qDebug() output:
rowCount returning 3 for parent **0x122ee138** type: 0
....
Qt::DisplayRole for row 0 ,column 0 pointer 0x122ee168 parent= **0x122ee138**
Qt::DisplayRole for row 1 ,column 0 pointer 0x122ee198 parent= **0x122ee138**
note 0x122ee138 - this is "internalPointer" value for parent node that contains 3 children
here are index() and parent() implementations:
QModelIndex Model_Tree::index(int row, int column, const QModelIndex &parent) const
{
void* p = 0;
if (!parent.isValid())
{
// This is 1st level
// we use our whole record
if (row < m_RowCount)
{
const TreeItem& treeItem = *(m_pRootItem->m_Children.at(row));
const LogRecord* pRecord = treeItem.m_pRecord;
const LogRecord& record = *pRecord;
if (column == 0)
{
p = (void*)&treeItem; // because createIndex() wants void* a 3rd parameter
}
else
{
const QList<QVariant>& fieldList = record.fieldList;
if (column <= fieldList.size())
{
const QVariant* pField = &(fieldList[column - 1]); // -1 Because we have extra column at left side
if ( (QMetaType::Type)(pField->type()) == QMetaType::QString )
{
//const QString *pString = static_cast<const QString*>(pField->data());
p = const_cast<void*>(pField->data());
}
if ( (QMetaType::Type)(pField->type()) == QMetaType::QStringList )
{
const QStringList *pStringList = static_cast<const QStringList*>(pField->data());
//const QString *pString = &(pStringList->at(0)) ;
p = const_cast<void*>( static_cast<const void*>( &(pStringList->at(0)) ) );
}
}
}
}
//qDebug() << "Creating index: " << row << ", " << column << ", " << p;
return createIndex(row, column, p);
}
if (0 != column)
{
//qDebug() << "Creating index: " << row << ", " << column << ", 0 -- if (0 != column)";
return createIndex(row, column, (void*)0);
}
p = parent.internalPointer();
const TreeItem* pTreeItem = (const TreeItem*)p;
if (0 == pTreeItem)
{
//qDebug() << "Creating index: " << row << ", " << column << ", 0 -- if (0 == pTreeItem)";
return createIndex(row, column, (void*)0);
}
if (row < pTreeItem->m_Children.size())
{
const TreeItem* pTreeSubItem = pTreeItem->m_Children.at(row).data();
//qDebug() << "Creating subline index: " << row << ", " << column << ", " << (void*)pTreeSubItem << "parent: " << pTreeItem;
return createIndex(row, column, (void*)pTreeSubItem);
}
//qDebug() << "Creating index: " << row << ", " << column << ", 0";
return createIndex(row, column, (void*)0);
}
QModelIndex Model_Tree::parent(const QModelIndex &index) const
{
if (!index.isValid())
{
QModelIndex qi;
qDebug() << "Creating INVACHILD PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
return qi;
}
const TreeItem* pChildItem = static_cast<const TreeItem*>(index.internalPointer());
if (0 == pChildItem)
{
QModelIndex qi;
qDebug() << "Creating NOTREEITEM PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
return qi;
}
const TreeItem* pParentItem = pChildItem->m_pParent;
if (0 == pParentItem)
{
QModelIndex qi;
qDebug() << "Creating NOPARENT PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
return qi;
}
qDebug() << "Creating PARENT index: " << pChildItem->m_RecordNumber << ", " << 0 << ", " << pParentItem;
return createIndex(pParentItem->m_RecordNumber, 0, (void*)pParentItem);
}
QVariant Model_Tree::data(const QModelIndex &index, int role) const
{
if (!(index.isValid()))
{
return QVariant();
}
switch (role)
{
case Qt::TextAlignmentRole:
return Qt::AlignTop;
case Qt::DisplayRole:
void* pInternal = index.internalPointer();
int column = index.column();
int row = index.row();
if (0 == column)
qDebug() << "Qt::DisplayRole for row " << row << ",column " << column << "pointer" << pInternal << "parent=" << index.parent().internalPointer();
if (0 == pInternal)
{
//qDebug() << "DR: internal pointer is 0";
return QVariant();
}
if (0 == column)
{
const TreeItem* pTreeItem = static_cast<const TreeItem*>(pInternal);
QString displayString;
QTextStream(&displayString) << pTreeItem->m_LogLineNumber;
if (pTreeItem->m_type == TreeItem::Subline)
{
QTextStream(&displayString) << " (" << row << "-th sub-line)"
<< " " << (*(pTreeItem->m_pSubline));
}
if (pTreeItem->m_type == TreeItem::Record)
{
if (pTreeItem->m_Children.size() > 0)
{
QTextStream(&displayString) << " (" << rowCount(index)/*pTreeItem->m_Children.size()*/ << " sub-lines)";
}
}
return displayString;
}
// for columns other than 0 index contains QString* as internal pointer
const QString* pText = static_cast<const QString*>(pInternal);
return *pText;
}
return QVariant();
}
Thank you Marek for trying to help me!
The problem was in my QSortFilterProxyModel-derived class that didn't take into account sub-items )))