Can I do pointer arithmetic on an STL::map::iterator - c++11

How to correctly use pointer arithmetics for stl::map::iterator ?
In example bellow I create stl::map and stl::map::iterator and try to access iterator second key by increasing the iterator.
#include <iostream>
#include <map>
using namespace std;
int main() {
map <string, string> peoples;
peoples["paul"] = "friend";
peoples["galactus"] = "foe";
map<string, string>::iterator my_iter = ++peoples.begin();
cout << my_iter->first << endl;
return 0;
}
When ++peoples.begin(); is used compilation is OK, but if 1 + peoples.begin(); is used, error is raised.
Question stands: How to use pointer arithmetics on stl::map::iterator ?
And are there any containers with similar difficulties, while I know that with stl::vector::iterator you can use pointer arithmetics?

Can I do pointer arithmetic on an STL::map::iterator
No. You can't do pointer arithmetic on iterators, since iterators are (in general) not pointers.
If you take a look at the documentation, you'll find that map::iterator is a bidirectional iterator. You'll also find that bidirectional iterators do not support addition operator.
You can find n'th successor of an iterator by applying the increment operator n times. There are standard algorithms for this as well: next and advance.
I know that with stl::vector::iterator you can use pointer arithmetics?
vector::iterator is a random access iterator. Those support addition operator.
PS. The original STL wasn't in a namespace, and the standard library is in the namespace std; not stl.

Related

Uniqueness of std::unique_ptr

I have been working on std::unique_ptr s but confused at some point about its semantics. From the documentation,
No two unique_ptr instances can manage the same object
But, even tough it is most probably a silly example, consider such a code.
std::unique_ptr<int> a(new int(10));
std::unique_ptr<int> b = std::unique_ptr<int>(a.get());
std::cout << *b << std::endl;
*a = 5;
std::cout << *b;
a and b is managing the same object here, and the output is 10 5. And of course I am getting an assertion failure error at the end on debug mode due to two unique ptrs trying to destruct same object at the end of scope.
I know it is silly and such usage is not advised, but I came across to this when it was not very obvious ( a class member calling another etc. ) and the assertion failure was the thing I started with.
My question is what the above sentence exactly means: it is posed by the standard and a decent compiler shouldnt allow you to do it (i am on vs2013 btw) or you must do it that way ( never cause two unique_ptrs point to same object) ( unlikely since the purpose of unique_ptrs is to make us less worried i suppose.) Or I should never use anything about raw pointers ( a.get() ) when unique_ptr s are involved.
Your last sentence is correct. As soon as you use raw pointers with a.get() as in the line below, you have thrown away all the promises that std::unique_ptr make to you.
std::unique_ptr<int> b = std::unique_ptr<int>(a.get());
The correct semantic to preserve the uniqueness while converting to a raw pointer would be to use a.release().
std::unique_ptr<int> b = std::unique_ptr<int>(a.release());
Of course, you would normally just use assignment or initializatoin with std::move if you were moving ownership between two std::unique_pointer instances, as given by the documentation. Either of the two lines below should be valid.
std::unique_ptr<int> b(std::move(a));
std::unique_ptr<int> b = std::move(a);
To make the std::move semantics more clear, consider the following test program.
#include <stdio.h>
#include <memory>
#include <stdlib.h>
int main(){
std::unique_ptr<int> a(new int(10));
printf("%p\n", a.get());
std::unique_ptr<int> b(std::move(a));
printf("%p\n", a.get());
printf("%p\n", b.get());
}
On my system, the output is the following. Observe that the first line and the last line match.
0x1827010
(nil)
0x1827010

Is it possible to write a generic function that distiguishes between an rvalue and an lvalue?

I am trying to learn rvalue references, as an exercise I tried to do answer the following.
Is it possible to write a function that can tell (at least at runtime, better if at compile time) if the passed value is a value (non reference), a rvalue or an lvalue? for a generic type? I want to extract as much information about the type as possible.
An alternative statement of the problem could be:
Can I have a typeid-like function that can tell as much as possible about the calling expression?, for example (and ideally) if the type is T, T&, T const&, or T&&.
Currently, for example, typeid drops some information about the type and one can do better (as in the example the const and non-const reference are distiguished). But how much better than typeid can one possibly do?
This is my best attempt so far. It can't distinguish between a rvalue and a "constant". First and second case in the example).
Maybe distiguishing case 1 and 2 is not possible in any circumstance? since both are ultimately rvalue? the the question is Even if both are rvalues can the two cases trigger different behavior?
In any case, it seems I overcomplicated the solution as I needed to resort to rvalue conditional casts, and ended up with this nasty code and not even 100% there.
#include<iostream>
#include<typeinfo>
template<class T>
void qualified_generic(T&& t){
std::clog << __PRETTY_FUNCTION__ << std::endl;
std::clog
<< typeid(t).name() // ok, it drops any qualification
<< (std::is_const<typename std::remove_reference<decltype(std::forward<T>(t))>::type>::value?" const":"") // seems to detect constness rigth
<< (std::is_lvalue_reference<decltype(std::forward<T>(t))>::value?"&":"")
<< (std::is_rvalue_reference<decltype(std::forward<T>(t))>::value?"&&":"") // cannot distiguish between passing a constant and an rvalue expression
<< std::endl
;
}
using namespace std;
int main(){
int a = 5;
int const b = 5;
qualified_generic(5); // prints "int&&", would plain "int" be more appropriate?
qualified_generic(a+1); // prints "int&&" ok
qualified_generic(a); // print "int&", ok
qualified_generic(b); // print "int const&", ok
}
Maybe the ultimate solution to distiguish between the cases will involve detecting a constexpr.
UPDATE: I found this talk by Scott Meyers where he claims that "The Standard sometimes requires typeid to give the 'wrong' answer". http://vimeo.com/97344493 about minute 44. I wonder if this is one of the cases.
UPDATE 2015: I revisited the problem using Boost TypeIndex and the result is still the same. For example using:
template<class T>
std::string qualified_generic(T&& t){
return boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&&>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&>().pretty_name();
}
Still it is not possible to distinguish the type of 5 and a+1 in the above example.

C++11 efficient vector member initialization?

What is the best way to initialize a vector member object in C++11? Will the compiler optimize away the copy in foo or will bar be more efficient?
#include <vector>
using namespace std;
// C++11 style
struct foo
{
vector<int> vec = vector<int>(256);
};
// traditional
struct bar
{
bar() : vec(256) {}
vector<int> vec;
};
In C++11 there probably isn't much difference between them. For example foo does not copy a large vector. The right hand side of the = is an rvalue and will be moved to the left hand side. The only difference is the creation (and quick removal) of the 0-element vector within foo. But that'll take up no time.
But, both C++11 and C++03 allow optimizations ('elision') to skip the assignment in foo. Therefore they can both be very efficient in both standards.

Does C++11 have wrappers for dynamically-allocated arrays like Boost's scoped_array?

I often need to deal with dynamically-allocated arrays in C++, and hence rely on Boost for scoped_array, shared_array, and the like. After reading through Stroustrup's C++11 FAQ and the C++11 Reference Wiki, I could not find a suitable replacement for these dynamic array wrappers that is provided by the C++11 standard. Is there something that I have overlooked, or do I have to continue relying on Boost?
There is a specialization of unique_ptr, like unique_ptr<T[]>.
#include <iostream>
#include <memory>
struct test
{
~test() { std::cout << "test::dtor" << std::endl; }
};
int main()
{
std::unique_ptr<test[]> array(new test[3]);
}
When you run it, you will get this messages.
test::dtor
test::dtor
test::dtor
If you want to use shared_ptr, you should use std::default_delete<T[]> for deleter since it doesn't have one like shared_ptr<t[]>.
std::shared_ptr<test> array(new test[3], std::default_delete<test[]>());
So far as vectors are intended as array wrappers, what if you use any suitable smart pointer with the vector as inner object?

const shared_ptr to shared_ptr

How can one convert a shared_ptr that points to a const object to a shared_ptr that points to a non-const object.
I am trying to do the following :
boost::shared_ptr<const A> Ckk(new A(4));
boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;
But it does not work.
'boost::const_pointer_cast' will do what you're asking for, but the obligatory second half of the answer is that you probably shouldn't use it. 99% of the time when it seems like you need to cast away the const property of a variable, it means that you have a design flaw. Const is sometimes more than just window dressing and casting it away may lead to unexpected bugs.
Without knowing more details of your situation one can't say for certain. But no discussion of const-cast is complete without mentioning this fact.
use boost::const_pointer_cast, documentation.
the proper way should be this
boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
std::const_cast_pointer makes a second managed pointer. After the cast you have a writable pointer and the original const-pointer. The pointee remains the same. The reference count has been increased by 1.
Note that const_cast is a builtin keyword, but const_pointer_cast is a template function in namespace std.
The writable pointer can then be used to change the value from under the shared_ptr<const T>. IMHO the writable pointer should only persist temporarily on the stack; otherwise there must be a design flaw.
I once wrote a small test program to make this clear to myself which I adapted for this thread:
#include <memory>
#include <iostream>
#include <cassert>
using namespace std;
typedef shared_ptr<int> int_ptr;
typedef shared_ptr<const int> const_int_ptr;
int main(void)
{
const_int_ptr Ckk(new int(1));
assert(Ckk.use_count() == 1);
cout << "Ckk = " << *Ckk << endl;
int_ptr kk = const_pointer_cast<int>(Ckk); // obtain a 2nd reference
*kk = 2; // change value under the const pointer
assert(Ckk.use_count() == 2);
cout << "Ckk = " << *Ckk << endl; // prints 3
}
Under UNIX or Windows/Cygwin, compile with
g++ -std=c++0x -lm const_pointer_cast.cpp

Resources