Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Questions about new range for (http://www.velocityreviews.com/forums/t754637-questions-about-new-range-for.html)

Adrian 10-05-2011 02:37 PM

Questions about new range for
 
Hi all,

I am trying out the new range for and I have some questions when it is
being used as a map.

I see the standard says (6.5.4) that range-based for is equivalent to
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}

So for a std::map I think the second _RangeT is a class type - is the
section that applies and it calls begin() and end() on my may - but the
example I tried with an iterator doesnt work.

My other general question is - Are the other examples correct/bad
style/work by luck etc. I dont understand how range-based for works with
a map.

Any help/discussion is appreciated.

Thanks

Adrian Cornish

#include <iostream>
#include <map>

int main(int argc, char *argv[])
{
typedef std::map<int, std::string> Map;
Map arr={{9, "nine"}, {8,"eight"}, {7,"seven"}, {6, "six"}, {5,
"five"}};

// Test1
for(std::pair<int, std::string> i : arr)
{
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

// same as Test1 I believe
// Test2
for(Map::value_type i : arr)
{
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

// Test3
//error: invalid initialization of reference of type
// 'std::pair<int, std::basic_string<char> >&' from expression of type
// 'std::pair<const int, std::basic_string<char> >'
//
// for(std::pair<int, std::string> &i : arr)
// {
// std::cout << i.first << ' ' << i.second << ',';
// }
// std::cout << std::endl;

// Test4
// Maybe this is not the same as Test3 - since the above will not
compile
for(Map::value_type &i : arr)
{
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

// Test5
for(const Map::value_type &i : arr)
{
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

// And this works but the not const reference of std::pair does not
// Test6
for(const std::pair<int, std::string> i : arr)
{
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

// Test7
// I really dont get why an iterator does not work? And what does it
mean by
// non-scalar type
// error: conversion from 'std::pair<const int, std::basic_string<char> >'
// to non-scalar type 'std::map<int, std::basic_string<char>
>::const_iterator

// {aka std::_Rb_tree_const_iterator<std::pair<const int,
// std::basic_string<char> > >}' requested
// for(Map::const_iterator i : arr)
// {
// std::cout << i->first << ' ' << i->second << ',';
// }
// std::cout << std::endl;

// Test8
for(auto i : arr)
{
// What is i here
std::cout << i.first << ' ' << i.second << ',';
}
std::cout << std::endl;

return 0;
}

Adrian 10-05-2011 02:58 PM

Re: Questions about new range for
 
On 10/5/2011 8:37 AM, Adrian wrote:
> So for a std::map I think the second _RangeT is a class type - is the
> section that applies and it calls begin() and end() on my may - but the
> example I tried with an iterator doesnt work.


Well I can answer that bit for myself - the iterator doesnt work because
of this
"for-range-declaration = *__begin;"

restor 10-05-2011 09:56 PM

Re: Questions about new range for
 
On Oct 5, 4:37*pm, Adrian <n...@bluedreamer.com> wrote:
> Hi all,
>
> I am trying out the new range for and I have some questions when it is
> being used as a map.
>
> I see the standard says (6.5.4) that range-based for is equivalent to
> {
> * * auto && __range = range-init;
> * * for ( auto __begin = begin-expr,
> * * * *__end = end-expr;
> * * * *__begin != __end;
> * * * *++__begin ) {
> * * * * * for-range-declaration = *__begin;
> * * * * * statement
> * * }
>
> }
>
> So for a std::map I think the second _RangeT is a class type - is the
> section that applies and it calls begin() and end() on my may - but the
> example I tried with an iterator doesnt work.
>
> My other general question is - Are the other examples correct/bad
> style/work by luck etc. I dont understand how range-based for works with
> a map.
>
> Any help/discussion is appreciated.
>
> Thanks
>
> Adrian Cornish
>
> #include <iostream>
> #include <map>
>
> int main(int argc, char *argv[])
> {
> * * typedef std::map<int, std::string> Map;
> * * Map arr={{9, "nine"}, {8,"eight"}, {7,"seven"}, {6, "six"}, {5,
> "five"}};
>
> * * // Test1
> * * for(std::pair<int, std::string> i : arr)
> * * {
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * // same as Test1 I believe
> * * // Test2
> * * for(Map::value_type i : arr)
> * * {
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * // Test3
> //error: invalid initialization of reference of type
> // 'std::pair<int, std::basic_string<char> >&' from expression of type
> // 'std::pair<const int, std::basic_string<char> >'
> //
> // * for(std::pair<int, std::string> &i : arr)
> // * {
> // * * *std::cout << i.first << ' ' << i.second << ',';
> // * }
> // * std::cout << std::endl;
>
> * * // Test4
> * * // Maybe this is not the same as Test3 - since the above will not
> compile
> * * for(Map::value_type &i : arr)
> * * {
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * // Test5
> * * for(const Map::value_type &i : arr)
> * * {
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * // And this works but the not const reference of std::pair does not
> * * // Test6
> * * for(const std::pair<int, std::string> i : arr)
> * * {
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * // Test7
> * * // I really dont get why an iterator does not work? And what doesit
> mean by
> * * // non-scalar type
> // error: conversion from 'std::pair<const int, std::basic_string<char> >'
> // to non-scalar type 'std::map<int, std::basic_string<char>
> *>::const_iterator
> // {aka std::_Rb_tree_const_iterator<std::pair<const int,
> // std::basic_string<char> > >}' requested
> // * for(Map::const_iterator i : arr)
> // * {
> // * * *std::cout << i->first << ' ' << i->second << ',';
> // * }
> // * std::cout << std::endl;
>
> * * // Test8
> * * for(auto i : arr)
> * * {
> * * * *// What is i here
> * * * *std::cout << i.first << ' ' << i.second << ',';
> * * }
> * * std::cout << std::endl;
>
> * * return 0;
>
>
>
>
>
>
>
> }


Hi,
I do not have any compiler that supports range-based for at hand but
from your examples it looks like you are using wrong type for map
values. Given the map of type std::map<int, std::string>, its
value_type is std::pair<const int, std::string>. Note the *const*.

Use the following in place of Test 3:

for( std::pair<const int, std::string> &i : arr )
{
std::cout << i.first << ' ' << i.second << ',';
}

Regards,
&rzej


All times are GMT. The time now is 09:47 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.