Not understanding how pointers and classes work together in this example - c++

Hmmmm I am stumped on this one, using Visual Studio 2012 I have only one error left on my project and I am dying to test it out. Yes it's for a C++ class and I hope I posted enough code.
I get the error:
C2227 left of ->writeData must point to class/struct/union/generic type
In the previous project this line had the element of the array of pointers ( an Employee* pointer I assume) and it worked like so:
Employee* myEmployees[MAX_EMPS];
...
myEmployees[i]->writeData(outputEmployee);
So I implement a vector of Employee*, and assume it also contains pointers:
MyVector<Employee*> employeePtrList;
I do the next couple steps a bit indirectly but have cleared this with Prof. Debry:
Employee* empPtr1 = new HourlyEmployee(EMP1_ID, EMP1_NAME, EMP1_ADDRESS, EMP1_PHONE, EMP1_HOURS, EMP1_WAGE);
2...
3...
4...
employeePtrList.push_back(empPtr1);
2...
3...
4...
Then later in the program this line is giving me the error:
employeePtrList.at(i)->writeData(outputEmployee);
I have tried various things, if I dereference it with *(employeePtrList) just for fun it changes the intellisense error but I still get the same:
C2227 left of ->writeData must point to class/struct/union/generic type
Any idears? Where I get stumped is understand that employeePtrLIst is an Employee pointer so maybe it's looking for at in the wrong class? I guess maybe I am not "pointing" to the function in the MyVector class properly?
Thanks

Without knowing exactly how MyVector works, a few things at first glance could be going wrong:
.at() might be returning a reference to an object (or even a copy of the object), thus you'd need to use the . operator.
Another possibility is that, if .at() returns an iterator of type Employee*, you might need to dereference the iterator (i.e. (*employeePtrList.at(i))->writeData(outputEmployee);) depending on the implementation.

Related

Why is my private member displayed as another type than it is defined as?

I'm currently working on a project in C++ and I'm just not allowed to push_back on my vector (compile error).
The method where everything seems to go wrong looks like this:
DetectionResult DetectionManager::Update(DetectionInput& input) const
{
std::vector<DetectionResultUnfiltered> results;
results.reserve(m_detectionModels.size());
for (auto& detectionModel : m_detectionModels)
(
std::future<void> future = std::async(std::launch::async, UpdateDetectionModelAsynchronously, detectionModel, &results, &input);
m_futures.push_back(future); // <-- Compile error only on this line
)
}
I think it is rather unimportant what exactly the other called method does and how those types are structured exactly. The only important thing should be that the field m_futures is of the type std::vector<std::future<void>>.
Even when hovering the m_futures in Visual Studio within that method, it clearly shows me that it is of the correct type (field) std::vector<std::future<void>> DetectionManager::m_futures.
But still the .push_back() call is underlined in red, and when hovered it shows the following error: no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=std::future<void>, _Alloc=std::allocator<std::future<void>>]" matches the argument list and object (the object has type qualifiers that prevent a match) - argument types are: (std::future<void>) - object type is: const std::vector<std::future<void>, std::allocator<std::future<void>>>
I'm pretty sure my vector is not really handled as a vector in this current case, because when auto completing the method calls on my vector I don't get even a suggestion for .push_back() or .emplace_back() or something like this. I think it is handled as an object of a type I imported from another library (opencv::mat or something like that), because at some point it was even shown like that when hovered.
And by the way,
the method call is not shown as an error when I do this:
(static_cast<std::vector<std::future<void>>>(m_futures)).push_back(future);
so by explicitly casting it to a vector it seems to work again.
I just don't know exactly what happens here. I've traced down and commented some includes to make sure nothing weird was included. And while doing that I figured out that I don't get any errors highlighted within the DetectionManager.h even when commenting out the #include (Even if not including ANYTHING in the .h at all, only the #include is needed when working with that type).
It doesn't even work on other vectors as well, so when implementing an example vector which only holds bools, I don't need to include the and everything looks right according to Visual Studio, which is weird enough since I didn't include or which I'm using as well.
Does anyone have any idea what it might be? Or how to track down this error?
Big thanks in advance!
As Borgleader correctly pointed out, the method was marked as const - but when pushing back, I am modifying the class field which is obviously not allowed.
The const was a leftover from an older design I just reworked and thus I completely forgot about it.
That paired with some other weird errors I had before (like the field being shown as a complete different type from some library I imported even though it was clearly declared as a vector) didn't help.
I still don't quite understand why my project is compiling when not including or within the header file at all even when I declare fields with those types, but at least that's not stopping me from building and running the program.

How to access to the second map iterator?

We are two students and we now have an epic big problem that we can't resolve. We asked our teacher for some help but he can't help us, so our last chance is this forum!
We're doing a project: a command interpreter of NPI files.
map<string,void(Interpreteur::*)()>::iterator trouve = interpreteur.myMap.find(saisie);
if(trouve == interpreteur.myMap.end())
cerr<<"command not found"<<endl;
else
(trouve->*second)();
We must use the object named "map" but we can't get the second parameter, named.. "Second". Why? Code Blocks told us the error is in the "else", here is the error:
'second' was not declared in this scope.
We have tried too:
map<string,void(Interpreteur::*)()>::iterator trouve = interpreteur.myMap.find(saisie);
if(trouve == interpreteur.myMap.end())
cerr<<"command not found"<<endl;
else
(trouve.second)();
And code blocks answered:
error: 'std::map, void (Interpreteur::*)()>::iterator' has no member named 'second'
If someone can help us, it will save our project, we must end it for tomorrow.. We will be very grateful.
Thank you very much for help, we can answer questions, if there are any :)
A std::map iterator points to a pair. So to access the pair's second element, do this:
trouve->second
Note that in your case, the type of that second element is "pointer to member function of Interpreteur," so to call it, you need to provide an Interpreteur object. Something like this:
(interpreteur.*(trouve->second))()

How can I tell lint to track a custodial pointer to a vector?

I have some code that loops and news up some pointers and stores them in a vector:
std::vector<InputBox*> m_octets;
...
InputBox* octet = new InputBox(rect, title, touch_num);
m_octets.push_back(octet);
In the class destructor I for_each over m_octets and invoke the destructor for each pointer. I think this is all good. It all compiles and the unit tests pass. The problem is Gimpel's PC-lint doesn't like it. It sees that `octet' is a custodial pointer that has not been freed (Warning 429). I can of course disable that warning but the manual (11.2.1) indicates there is a semantic for this. I would have thought would work:
-sem(*push_back, custodial (1))
Unfortunately it has no effect. I've tried various combinations including fully specifying m_octets.push_back but nothing seems to work. Does anybody know the proper form of this command for the example given?
This one works fine for me: -sem(std::vector::push_back, custodial(1))

strange error in passing pointers (*&) in constructor

i'm not a c++ guru at all, and i've tried to replicate this error in variuos little trials. the fact is that when i do a little program with 2 o 3 classes with what i wanto to do, there is no error. but in the main applicaiton i'm tring to write the error persist even if i've tried a lot of (even nonsense) solutions.
the problem is that i have a main class that instantiate some resources (as pointers) and a strategy pattern that istantiate different concrete behaviours that take in constructors thoose resources.
in main app, init():
device = new Kinect();
controls = new Gui();
UserPositionBehaviour = new UserPositionBehaviour(device, controls);
and, behaviour constructor:
UserPositionBehaviour(Kinect * device, Gui * controls);
this is the error:
src/App.cpp:30: error: no matching function for call to ‘UserPositionBehaviour::UserPositionBehaviour(Kinect*&, ofTrueTypeFont*&, ofxGui*&)’
src/UserPositionBehaviour.h:15: note: candidates are: UserPositionBehaviour::UserPositionBehaviour(Kinect*, ofxGui*, ofTrueTypeFont*)
src/UserPositionBehaviour.h:13: note: UserPositionBehaviour::UserPositionBehaviour(const UserPositionBehaviour&)
eh?? hei, what is happening? i'm passing pointers, not *& (that i don't event know how to read)
some advice?
i've tried to replicate the error with a simple case builds only on couts but there are no problems so mayebe there is some error hidden somewhereelse..
According to the error message, you're calling the constructor with three arguments, not two, and you've got the last two the wrong way round.
If that's the real error message, then your code probably looks like:
UserPositionBehaviour = new UserPositionBehaviour(device, font, controls);
// ^^^^ ^^^^^^^^
and should be:
UserPositionBehaviour = new UserPositionBehaviour(device, controls, font);
// ^^^^^^^^ ^^^^
If your code really does look like what you've posted, and gives that error message, then something really weird is happening; in that case, please post a complete compilable example so we can investigate further.
You can ignore the extra &s in gcc's error message: it's a slightly odd way of saying that it's looking for functions that take their arguments by either value or reference.
The code that causes the error passes three arguments (not two as you think), and it has the last two in the wrong order. You must be looking at the wrong version of the source files, or something like that.
Check for silly things like out-of-date copies of src/UserPositionBehaviour.h and src/App.cpp lying around, that you might be looking at instead of looking at the version the compiler is actually compiling. Or maybe you're using pre-compiled headers, and something has gone wrong there.
The error message for a not-found function will usually look like that. The Foo *& is type "reference to pointer to Foo", and it just means that your argument expression is an lvalue pointer-to-Foo. That call could match a function that takes a pointer by value, or a function that takes a pointer by reference. The compiler hasn't found either, but it has to pick something for the error message, and your compiler picks that one. If your call contained the argument expression device+0 instead of device, then it would not be eligible to pass by non-const reference (because the result of device+0 is a temporary), and the error message wouldn't have the &.
The code should compile if you truly have the constructor
UserPositionBehaviour(Kinect * device, Gui * controls);
defined, which, according to the compiler, you don't:
src/UserPositionBehaviour.h:15: note: candidates are:
UserPositionBehaviour::UserPositionBehaviour(Kinect*, ofxGui*,
ofTrueTypeFont*) src/UserPositionBehaviour.h:13: note:
UserPositionBehaviour::UserPositionBehaviour(const
UserPositionBehaviour&)
The *& simply means you pass the pointer by reference - i.e. it can be modified inside the constructor.

Remove never-run call to templated function, get allocation error on run-time

I have a piece of templated code that is never run, but is compiled. When I remove it, another part of my program breaks.
First off, I'm a bit at a loss as to how to ask this question. So I'm going to try throwing lots of information at the problem.
Ok, so, I went to completely redesign my test project for my experimental core library thingy. I use a lot of template shenanigans in the library. When I removed the "user" code, the tests gave me a memory allocation error. After quite a bit of experimenting, I narrowed it down to this bit of code (out of a couple hundred lines):
void VOODOO(components::switchBoard &board) {
board.addComponent<using_allegro::keyInputs<'w'> >();
}
Fundementally, what's weirding me out is that it appears that the act of compiling this function (and the template function it then uses, and the template functions those then use...), makes this bug not appear. This code is not being run. Similar code (the same, but for different key vals) occurs elsewhere, but is within Boost TDD code.
I realize I certainly haven't given enough information for you to solve it for me; I tried, but it more-or-less spirals into most of the code base. I think I'm most looking for "here's what the problem could be", "here's where to look", etc. There's something that's happening during compile because of this line, but I don't know enough about that step to begin looking.
Sooo, how can a (presumably) compilied, but never actually run, bit of templated code, when removed, cause another part of code to fail?
Error:
Unhandled exceptionat 0x6fe731ea (msvcr90d.dll) in Switchboard.exe:
0xC0000005: Access violation reading location 0xcdcdcdc1.
Callstack:
operator delete(void * pUser Data)
allocator< class name related to key inputs callbacks >::deallocate
vector< same class >::_Insert_n(...)
vector< " " >::insert(...)
vector<" ">::push_back(...)
It looks like maybe the vector isn't valid, because _MyFirst and similar data members are showing values of 0xcdcdcdcd in the debugger. But the vector is a member variable...
Update: The vector isn't valid because it's never made. I'm getting a channel ID value stomp, which is making me treat one type of channel as another.
Update:
Searching through with the debugger again, it appears that my method for giving each "channel" it's own, unique ID isn't giving me a unique ID:
inline static const char channel<template args>::idFunction() {
return reinterpret_cast<char>(&channel<CHANNEL_IDENTIFY>::idFunction);
};
Update2: These two are giving the same:
slaveChannel<switchboard, ALLEGRO_BITMAP*, entityInfo<ALLEGRO_BITMAP*>
slaveChannel<key<c>, char, push<char>
Sooo, having another compiled channel type changing things makes sense, because it shifts around the values of the idFunctions? But why are there two idFunctions with the same value?
you seem to be returning address of the function as a character? that looks weird. char has much smaller bit count than pointer, so it's highly possible you get same values. that could reason why changing code layout fixes/breaks your program
As a general answer (though aaa's comment alludes to this): When something like this affects whether a bug occurs, it's either because (a) you're wrong and it is being run, or (b) the way that the inclusion of that code happens to affect your code, data, and memory layout in the compiled program causes a heisenbug to change from visible to hidden.
The latter generally occurs when something involves undefined behavior. Sometimes a bogus pointer value will cause you to stomp on a bit of your code (which might or might not be important depending on the code layout), or sometimes a bogus write will stomp on a value in your data stack that might or might not be a pointer that's used later, or so forth.
As a simple example, supposing you have a stack that looks like:
float data[10];
int never_used;
int *important pointer;
And then you erroneously write
data[10] = 0;
Then, assuming that stack got allocated in linear order, you'll stomp on never_used, and the bug will be harmless. However, if you remove never_used (or change something so the compiler knows it can remove it for you -- maybe you remove a never-called function call that would use it), then it will stomp on important_pointer instead, and you'll now get a segfault when you dereference it.