Get a pointer to a subordinate YAML::Node - c++

I am writing a config file library, and I'd like to have a pointer to a sub-node to pass to functions expecting YAML::Node*, for example for building up a YAML document.
I can create a new Node and get a pointer easily enough:
YAML::Node* foo = new YAML::Node(); // Null node
and I can add a new sub node easily enough:
(*foo)["bar"] = baz;
However, I don't know how to get a pointer to (*foo)["bar"]. If I try
&((*foo)["bar"]);
I get error: taking address of temporary, which is true, because the [] operator returns a YAML::Node. Is there a way to get a pointer to (*foo)["bar"] so that I can pass it to something like
void f(YAML::Node* const blah)
{
(*blah)["banana"] = 1;
}
which is useful, because then I can build up a tree with recursive calls to f.

Just pass a YAML::Node, not a pointer. YAML::Node is already a reference type, so you can pass it like a pointer.

Related

Get object from pointer C++

I have a vector of objects (DimensionItem) and I want to push another item to the vector. I only have a pointer to the object I wish to push. How can I get the object from the pointer.
(New to pointers, very possible I'm am fundamentally misunderstanding something)
DimensionItem *selected_Item = dynamic_cast<DimensionItem*>(g_items[i]); //g_items is a list of items taken from my scene
vector<DimensionItem> DimItems;
DimItems.push_back(selected_Item);
The error message is:
no matching function for call to 'std::vector::push_back(DimensionItem*&)'
You probably want:
DimensionItem& selected_Item = dynamic_cast<DimensionItem&>(*g_items[i]); // Throws if g_items[i] is not DimensionItem.
vector<DimensionItem> DimItems;
DimItems.push_back(selected_Item); // Stores a copy of selected_Item.
dynamic_cast<DimensionItem*>(g_items[i]) returns a null pointer if g_items[i] is not a DimensionItem, so the code would need to check the pointer for null before dereferencing it.
Whereas dynamic_cast<DimensionItem&>(*g_items[i]) throws an exception in that case.

How to get a member function pointer in MSVC?

I'm not going to get into too much of the details on the Excel side of things, I essentially took code from this example:
C++ app automates Excel (CppAutomateExcel)
solution1.cpp
So I've tried this code in MSVC and it compiles:
class foo { public: virtual void bar(){} };
int main()
{
void (foo::*p)() = &foo::bar;
}
But similar code to capture the address of the move function in Excel does not work:
int main()
{
Excel::_ApplicationPtr spXlApp;
HRESULT hr = spXlApp.CreateInstance(__uuidof(Excel::Application));
Excel::WorkbooksPtr spXlBooks = spXlApp->Workbooks;
Excel::_WorkbookPtr spXlBook = spXlBooks->Add();
Excel::_WorksheetPtr spXlSheet = spXlBook->ActiveSheet;
HRESULT(Excel::_Worksheet::*pMove)(...) = &spXlSheet->Excel::_Worksheet::Move;
<... irrelevant code ...>
return 0;
}
This has the following compiler error:
error C2276: '&': illegal operation on bound member function expression
If I remove the &, it says I should add it back:
error C3867: 'Excel::_Worksheet::Move': non-standard syntax; use '&' to create a pointer to member
Any help on what to do here would be greatly appreciated.
You say in your question "but similar code..." and then you show code in which you do not do the same thing. Try using the same syntax for setting pMove as you used for setting p in your smaller example. Try something like &Excel::_Worksheet::Move; (without the "spXlSheet->").
If you can specify the specific instance of the object for which to call the function pointer at the time that you set the function pointer as you have there, I'm not aware of such a capability. After dropping spXlSheet-> from where you set the variable, use it instead where you want to call the function pointer.
You need to declare the method pointer like this instead:
// or whatever parameter type Move() actually uses...
void (Excel::_Worksheet::*pMove)(tagVARIANT, tagVARIANT) = &Excel::_Worksheet::Move;
Then, to actually call pMove(), you would have to do something like this:
Excel::_WorksheetPtr spXlSheet = ...;
(spXlSheet.Get()->*pMove)(...);

returning a pointer to an IXMLDOMNode as a parameter...what a pain

I have to polish up my c++ Knowledge, since we have to realize a specific module with MS vc++. OK, here is what I like to do:
I have a global MS DOMDocument which holds a number of nodes. These nodes are describing the object data... I receive a uniquie objectidentifier and have to search the DOM for the object and map this to a given structure...
so I have this:
IXMLDOMNode *Node = NULL;
if (FindObject(objectIdentifier, &Node))
{
nreturn = MapObject(Node, &pVarBind->value);
}
This should define a pointer to a node and calls the FindObject Method with the reference of the pointer. If it succeeds the MapObject method is called..
However "Node" is always NULL after Findobject, but inside the method it finds it object and tries to pass it back...
Findobject Looks like this:
bool MyController::FindObject(const string aObjectIdentifier, IXMLDOMNode **aObject)
{
bool success = false;
IXMLDOMNode *pXMLEntry = NULL;
//....searching the DOM
if (success)
{
aObject = &pXMLEntry;
}
return success;
}
Any ideas what might be wrong?
In FindObject, when you assign
aObject = &pXMLEntry;
What you're doing is overwriting your local parameter. What you want to do is write to the value pointed at by your parameter, like this:
*aObject = pXMLEntry;

C++ shared_ptr and direct buffer enqueueing. How?

I need to make small code refactoring i queueing/dequeueing operation in multi-thread application. Current implementation is:
enqueueing function is called with argument:
enqueue(obj_ptr item)
where obj_ptr is pointer to class obj created using shared_ptr. Then, given items (type obj_ptr) are enqueued in std list
list<obj_ptr>
and simply dequeued using front() and pop_front() and sent further. Everything works fine in this implementation.
What i want to do is:
Enqueue this items in special list using its API:
a_enqueue(void *buffer)
So I need the direct address to buffer.
I was thinking about use:
item->get()
which returns type obj but then I could only dequeue obj, not obj_ptr which is expected to next operations after dequeueing (+ I would loose information about class references and it will destroy multi-thread app)
I was thinking about provide to list pointer to obj_ref item:
a_enqueue(&item)
But item is created in some function long time ago and put as argument many times (not as pointer) and it is not possible to find direct address to it.
The best way for me is to enqueue buffer obj (item->get()), then dequeue and find somehow the same reference obj_ptr item I used in get(). Is it possible? Any other ideas?
Thanks.
Edit: Dequeue call is:
a_dequeue(void **buffer)
What does the API dequeue look like?
Usually if you're enqueueing void *, you're also defining a handler function so you can do something like this...
void enqueue_ptr (obj_ptr enqueue_me)
{
// Making a copy on the heap increments the ptr count
obj_ptr * heap_ptr = new obj_ptr(enqueue_me);
a_enqueue (heap_ptr);
}
obj_ptr dequeue_ptr (void)
{
// You might need casting to change void * to obj_ptr *
obj_ptr * heap_ptr;
a_dequeue (&heap_ptr);
// Sticking the copy in an auto_ptr decrements the ptr count when we leave scope.
std::auto_ptr<obj_ptr> obj_pptr(heap_ptr);
return *obj_pptr;
}
Basically, you treat the obj_ptr the same as you would any other object being passed around as a void *.

Can't use QString in a QLineEdit nor QComboBox as a parameter

I'm trying to make a function that replace the text inside a QLineEdit when the user want to revert is name to default using a QPushButton.
This is where the code is getting "saved".
`//Must get information in the DB
lineditPlayerName = new QLineEdit("Nouveau Profil");
nameAsDefault = new QString(lineditPlayerName->text());
languageAsDefault = new QString(comboBoxlanguage->currentText());`
This is the function i use to change the value back to default
//This code works
void ProfileManager::revertName(){
lineditPlayerName->setText("nameAsDefault");
btnRevertName->setEnabled(false);
}
But I need it like this :
//This code does'nt
void ProfileManager::revertName(){
lineditPlayerName->setText(NameAsDefault);
btnRevertName->setEnabled(false);
}
I can't get it to work it give's me this error:
no matching function for call to 'QLineEdit::setText(QString*&)'
Thanks
You must dereference the NameAsDefault variable
void ProfileManager::revertName(){
lineditPlayerName->setText(*NameAsDefault);
// ^ Here I dereferenced the pointer
btnRevertName->setEnabled(false);
}
The type of nameAsDefault is pointer to a QString. However QLineEdit::setText expects a QString object, not a pointer. Therefore the compiler tells you that there is no function which expects a pointer.
I did not see your declaration of the nameAsDefault variable, but since
nameAsDefault = new QString(lineditPlayerName->text());
compiles and new returns a pointer, I suppose it is a pointer.
Also, what is probably more important is that you should almost never allocate objects using new. Especially not objects from the Qt library, which are implicitly shared.