isn't iterator an object? - c++

this is my code:
for (list<moveStringTree>::iterator tempIterator=moveList.begin();tempIterator!=moveList.end(); ++tempIterator)
{
moveStringTree *move = tempIterator;
}
but it gives me an error. if there is a castingway, I don't like it. it is too time consuming. anyway I want to go throw a list and do something with each object in it. what can I do?
foreach won't help. because only it will give a copy.

isn't iterator an object?
It is. An object in C++ is equivalent to a memory location holding a value – no more, no less. However, I don’t see how this relates to the rest of the question.
but it gives me an error. if there is a castingway, I don't like it. it is too time consuming.
I have no idea what this means. But just in case you meant copy: no, it’s probably not too time-consuming. But if it is – don’t worry; use a reference.
moveStringTree& move = *tempIterator;
foreach won't help. because only it will give a copy.
Nonsense. foreach does the same as manually iterating. So you can also use it with a copy:
for (auto& o : moveList) {
// Do something.
}

You can use an iterator as if it was a pointer, but it isn't actually one. There is a dance that you can do to grab a pointer out of it, though:
moveStringTree *move = &*tempIterator;
The * resolves to a reference to the element that the iterator refers to, and the & returns the address of that element. The end result is a pointer.
Of course, you probably shouldn't do that. This:
tempIterator->doSomething();
works just fine.

Try:
moveStringTree *move = & (*tempIterator) ;
(the parentheses aren't strictly necessary)
The iterator itself is not a pointer to the object, but overloads * to return a reference to the object it refers to; from it you can get a pointer using the normal &.
Notice that normally you don't need to do this, since the iterator overloads also the -> operator, so you can access the object's members using the usual -> syntax.

In fact, you can gain a reference from std::for_each. moveStringTree* move = &*tempIterator; would be correct. However, more directly, you can simply use tempIterator as if it was already a pointer to the object in question.
for(auto it=moveList.begin();it!=moveList.end(); ++it) {
it->f(); // well formed if moveStringTree::f()
}

Related

Using boost::shared_ptr to refer to iterator without copying data?

Inside a loop I need to call a function which has an argument of type pcl::PointIndicesPtr. This is actually a boost::shared_ptr< ::pcl::PointIndices>. Is there a way to do this without having to copy the underlying data? I only could it get to work by using make_shared, which copies the object if I understand it correctly.
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
{
pcl::PointIndicesPtr indices_ptr2 =boost::make_shared<pcl::PointIndices>(*it);
}
For example this will crash at runtime:
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
{
pcl::PointIndices test = *it;
pcl::PointIndicesPtr indices_ptr3(&test);
}
The answer depends on the implementation of the function you are calling and what else your code does with the object. There is no "one right answer".
For example, if the function can't possibly access the object after it returns, the right answer might be to wrap the existing object with a shared_ptr with a dummy destructor. But if the function stashes the shared_ptr, that won't work.
If your own code never modifies the object, constructing the object with make_shared in the first place may be the right answer. But if your code modifies the object while the function expects it not to change later, that won't work.
You have to make a decision based on all the information.
The most important question to answer -- why does the function you are calling take a shared_ptr? Does it have a good reason? If so, what is that reason? If not, why not change it to take a reference?
Could you use BOOST_FOREACH?
i.e.
BOOST_FOREACH(pcl::PointIndiciesPtr ptr; cluster_indicies)
{
//do something with shared_ptr
}

Is it possible to initialize reference variables later?

Best explained with an example:
Class banana {
int &yumminess;
banana::banana() {
//load up a memory mapped file, create a view
//the yumminess value is the first thing in the view so
yumminess = *((int*)view);
}
}
But that doesn't work :/ there is no way I can know where the view is going to be when I dreclare the "yumminess" reference variable. Right now i just use a pointer and dereference it all the time, is there any way to bring this little extra bit of convenience to my class?
In short: No, it's intentionally not possible.
Think twice: Something like uninitialized references cannot really exist; such wouldn't make sense at all.
Thus they'll need to be set at the time of construction of the enclosing class, or at a point of static initialization.
You'll need to use pointers for such case.
Besides note that
yumminess = (int*)view;
would be wrongly casted (to a pointer) anyway.
"Right now i just use a pointer and dereference it all the time ..."
That's also easy to overcome writing an appropriate member function to access the reference.
int* yumminess;
// ...
int& yumminessRef() {
if(!yumminess) {
throw some_appropriate_exception("`yumminess` not initialized properly.");
}
return *yumminess;
}
No, not directly.
If you think the pointer is inconvenient, have a look at std::optional.

In C++ if a pointer is returned and immediately dereferenced, will the two operations be optimized away?

In C++ if I get and return the address of a variable and the caller then immediately dereferences it, will the compiler reliably optimize out the two operations?
The reason I ask is I have a data structure where I'm using an interface similar to std::map where find() returns a pointer (iterator) to a value, and returns NULL (there is no trivial .end() equivalent) to indicate that the value has not been found.
I happen to know that the variables being stored are pointers, so returning NULL works fine even if I returned the value directly, but it seems that returning a pointer to the value is more general. Otherwise if someone tried to store an int there that was actually 0 the data structure would claim it isn't there.
However, I'm wondering if there's even any loss in efficiency here, seeing as the compiler should optimize away actions that just undo the effect of each other. The problem is that the two are separated by a function return so maybe it wouldn't be able to detect that they just undo each other.
Lastly, what about having one private member function that just returns the value and an inline public member function that just takes the address of the value. Then at least the address/dereference operations would take place together and have a better chance of being optimized out, while the whole body of the find() function is not inlined.
private:
V _find(key) {
... // a few dozen lines...
}
public:
inline V* find(key) {
return &_find(key);
}
std::cout << *find(a_key);
This would return a pointer to a temporary, which I didn't think about. The only thing that can be done similar to this is to do a lot of processing in the _find() and do the last step and the return of the pointer in find() to minimize the amount of inlined code.
private:
W* _find(key) {
... // a few dozen lines...
}
public:
inline V* find(key) {
return some_func(_find(key)); // last steps on W to get V*
}
std::cout << *find(a_key);
Or as yet another responder mentioned, we could return a reference to V in the original version (again, not sure why we're all blind to the trivial stuff at first glance... see discussion.)
private:
V& _find(key) {
... // a few dozen lines...
}
public:
inline V* find(key) {
return &_find(key);
}
std::cout << *find(a_key);
_find returns a temporary object of type V. find then attempts to take the address of the temporary and return it. Temporary objects don't last very long, hence the name. So the temporary returned by _find will be destroyed after getting its address. And therefore find will return a pointer to a previously destroyed object, which is bad.
I've seen it go either way. It really depends on the compiler and the level optimization. Even when it does get inlined, I've seen cases where the compiler will not optimize this out.
The only way to see if it does get optimized out it is to actually look at the disassembly.
What you should probably do is to make a version where you manually inline them. Then benchmark it to see if you actually get a noticeable performance gain. If not, then this whole question is moot.
Your code (even in its second incarnation) is broken. _find returns a V, which find destroys immediately before returning its address.
If _find returned a V& to an object that outlives the call (thus producing a correct program), then the dereference would be a no-op, since a reference is no different to a pointer at the machine code level.

Is it wrong to dereference a pointer to get a reference?

I'd much prefer to use references everywhere but the moment you use an STL container you have to use pointers unless you really want to pass complex types by value. And I feel dirty converting back to a reference, it just seems wrong.
Is it?
To clarify...
MyType *pObj = ...
MyType &obj = *pObj;
Isn't this 'dirty', since you can (even if only in theory since you'd check it first) dereference a NULL pointer?
EDIT: Oh, and you don't know if the objects were dynamically created or not.
Ensure that the pointer is not NULL before you try to convert the pointer to a reference, and that the object will remain in scope as long as your reference does (or remain allocated, in reference to the heap), and you'll be okay, and morally clean :)
Initialising a reference with a dereferenced pointer is absolutely fine, nothing wrong with it whatsoever. If p is a pointer, and if dereferencing it is valid (so it's not null, for instance), then *p is the object it points to. You can bind a reference to that object just like you bind a reference to any object. Obviously, you must make sure the reference doesn't outlive the object (like any reference).
So for example, suppose that I am passed a pointer to an array of objects. It could just as well be an iterator pair, or a vector of objects, or a map of objects, but I'll use an array for simplicity. Each object has a function, order, returning an integer. I am to call the bar function once on each object, in order of increasing order value:
void bar(Foo &f) {
// does something
}
bool by_order(Foo *lhs, Foo *rhs) {
return lhs->order() < rhs->order();
}
void call_bar_in_order(Foo *array, int count) {
std::vector<Foo*> vec(count); // vector of pointers
for (int i = 0; i < count; ++i) vec[i] = &(array[i]);
std::sort(vec.begin(), vec.end(), by_order);
for (int i = 0; i < count; ++i) bar(*vec[i]);
}
The reference that my example has initialized is a function parameter rather than a variable directly, but I could just have validly done:
for (int i = 0; i < count; ++i) {
Foo &f = *vec[i];
bar(f);
}
Obviously a vector<Foo> would be incorrect, since then I would be calling bar on a copy of each object in order, not on each object in order. bar takes a non-const reference, so quite aside from performance or anything else, that clearly would be wrong if bar modifies the input.
A vector of smart pointers, or a boost pointer vector, would also be wrong, since I don't own the objects in the array and certainly must not free them. Sorting the original array might also be disallowed, or for that matter impossible if it's a map rather than an array.
No. How else could you implement operator=? You have to dereference this in order to return a reference to yourself.
Note though that I'd still store the items in the STL container by value -- unless your object is huge, overhead of heap allocations is going to mean you're using more storage, and are less efficient, than you would be if you just stored the item by value.
My answer doesn't directly address your initial concern, but it appears you encounter this problem because you have an STL container that stores pointer types.
Boost provides the ptr_container library to address these types of situations. For instance, a ptr_vector internally stores pointers to types, but returns references through its interface. Note that this implies that the container owns the pointer to the instance and will manage its deletion.
Here is a quick example to demonstrate this notion.
#include <string>
#include <boost/ptr_container/ptr_vector.hpp>
void foo()
{
boost::ptr_vector<std::string> strings;
strings.push_back(new std::string("hello world!"));
strings.push_back(new std::string());
const std::string& helloWorld(strings[0]);
std::string& empty(strings[1]);
}
I'd much prefer to use references everywhere but the moment you use an STL container you have to use pointers unless you really want to pass complex types by value.
Just to be clear: STL containers were designed to support certain semantics ("value semantics"), such as "items in the container can be copied around." Since references aren't rebindable, they don't support value semantics (i.e., try creating a std::vector<int&> or std::list<double&>). You are correct that you cannot put references in STL containers.
Generally, if you're using references instead of plain objects you're either using base classes and want to avoid slicing, or you're trying to avoid copying. And, yes, this means that if you want to store the items in an STL container, then you're going to need to use pointers to avoid slicing and/or copying.
And, yes, the following is legit (although in this case, not very useful):
#include <iostream>
#include <vector>
// note signature, inside this function, i is an int&
// normally I would pass a const reference, but you can't add
// a "const* int" to a "std::vector<int*>"
void add_to_vector(std::vector<int*>& v, int& i)
{
v.push_back(&i);
}
int main()
{
int x = 5;
std::vector<int*> pointers_to_ints;
// x is passed by reference
// NOTE: this line could have simply been "pointers_to_ints.push_back(&x)"
// I simply wanted to demonstrate (in the body of add_to_vector) that
// taking the address of a reference returns the address of the object the
// reference refers to.
add_to_vector(pointers_to_ints, x);
// get the pointer to x out of the container
int* pointer_to_x = pointers_to_ints[0];
// dereference the pointer and initialize a reference with it
int& ref_to_x = *pointer_to_x;
// use the reference to change the original value (in this case, to change x)
ref_to_x = 42;
// show that x changed
std::cout << x << '\n';
}
Oh, and you don't know if the objects were dynamically created or not.
That's not important. In the above sample, x is on the stack and we store a pointer to x in the pointers_to_vectors. Sure, pointers_to_vectors uses a dynamically-allocated array internally (and delete[]s that array when the vector goes out of scope), but that array holds the pointers, not the pointed-to things. When pointers_to_ints falls out of scope, the internal int*[] is delete[]-ed, but the int*s are not deleted.
This, in fact, makes using pointers with STL containers hard, because the STL containers won't manage the lifetime of the pointed-to objects. You may want to look at Boost's pointer containers library. Otherwise, you'll either (1) want to use STL containers of smart pointers (like boost:shared_ptr which is legal for STL containers) or (2) manage the lifetime of the pointed-to objects some other way. You may already be doing (2).
If you want the container to actually contain objects that are dynamically allocated, you shouldn't be using raw pointers. Use unique_ptr or whatever similar type is appropriate.
There's nothing wrong with it, but please be aware that on machine-code level a reference is usually the same as a pointer. So, usually the pointer isn't really dereferenced (no memory access) when assigned to a reference.
So in real life the reference can be 0 and the crash occurs when using the reference - what can happen much later than its assignemt.
Of course what happens exactly heavily depends on compiler version and hardware platform as well as compiler options and the exact usage of the reference.
Officially the behaviour of dereferencing a 0-Pointer is undefined and thus anything can happen. This anything includes that it may crash immediately, but also that it may crash much later or never.
So always make sure that you never assign a 0-Pointer to a reference - bugs likes this are very hard to find.
Edit: Made the "usually" italic and added paragraph about official "undefined" behaviour.

Why Can't I store references in a `std::map` in C++?

I understand that references are not pointers, but an alias to an object. However, I still don't understand what exactly this means to me as a programmer, i.e. what are references under the hood?
I think the best way to understand this would be to understand why it is I can't store a reference in a map.
I know I need to stop thinking of references as syntactic suger over pointers, just not sure how to :/
They way I understand it, references are implemented as pointers under the hood. The reason why you can't store them in a map is purely semantic; you have to initialize a reference when it's created and you can't change it afterward anymore. This doesn't mesh with the way a map works.
You should think of a reference as a 'const pointer to a non-const object':
MyObject& ~~ MyObject * const
Furthermore, a reference can only be built as an alias of something which exists (which is not necessary for a pointer, though advisable apart from NULL). This does not guarantee that the object will stay around (and indeed you might have a core when accessing an object through a reference if it is no more), consider this code:
// Falsifying a reference
MyObject& firstProblem = *((MyObject*)0);
firstProblem.do(); // undefined behavior
// Referencing something that exists no more
MyObject* anObject = new MyObject;
MyObject& secondProblem = *anObject;
delete anObject;
secondProblem.do(); // undefined behavior
Now, there are two requirements for a STL container:
T must be default constructible (a reference is not)
T must be assignable (you cannot reset a reference, though you can assign to its referee)
So, in STL containers, you have to use proxys or pointers.
Now, using pointers might prove problematic for memory handling, so you may have to:
use smart pointers (boost::shared_ptr for example)
use a specialized container: Boost Pointer Container Library
DO NOT use auto_ptr, there is a problem with assignment since it modifies the right hand operand.
Hope it helps :)
The important difference apart from the syntactic sugar is that references cannot be changed to refer to another object than the one they were initialized with. This is why they cannot be stored in maps or other containers, because containers need to be able to modify the element type they contain.
As an illustration of this:
A anObject, anotherObject;
A *pointerToA=&anObject;
A &referenceToA=anObject;
// We can change pointerToA so that it points to a different object
pointerToA=&anotherObject;
// But it is not possible to change what referenceToA points to.
// The following code might look as if it does this... but in fact,
// it assigns anotherObject to whatever referenceToA is referring to.
referenceToA=anotherObject;
// Has the same effect as
// anObject=anotherObject;
actually you can use references in a map. i don't recommend this for big projects as it might cause weird compilation errors but:
map<int, int&> no_prob;
int refered = 666;
no_prob.insert(std::pair<int, int&>(0, refered)); // works
no_prob[5] = 777; //wont compile!!!
//builds default for 5 then assings which is a problem
std::cout << no_prob[0] << std::endl; //still a problem
std::cout << no_prob.at(0) << std::endl; //works!!
so you can use map but it will be difficult to guaranty it will be used correctly, but i used this for small codes (usually competitive) codes
A container that stores a reference has to initialize all its elements when constructed and therefore is less useful.
struct container
{
string& s_; // string reference
};
int main()
{
string s { "hello" };
//container {}; // error - object has an uninitialized reference member
container c { s }; // Ok
c.s_ = "bye";
cout << s; // prints bye
}
Also, once initialized, the storage for the container elements cannot be changed. s_ will always refer to the storage of s above.
This post explains how pointers are implemented under the hood - http://www.codeproject.com/KB/cpp/References_in_c__.aspx, which also supports sebastians answer.