template with smart pointer iterator

for (const auto& elem : coll) {
What can auto be replaced with? I tried Coll::iterator but that doesn't work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
 * by Nicolai M. Josuttis, Addison-Wesley, 2012
 *
 * (C) Copyright Nicolai M. Josuttis 2012.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <string>
#include <set>
#include <deque>
#include <algorithm>
#include <memory>

class Item {
  private:
    std::string name;
    float  price;
  public:
    Item (const std::string& n, float p = 0) : name(n), price(p) {
    }
    std::string getName () const {
        return name;
    }
    void setName (const std::string& n) {
        name = n;
    }
    float getPrice () const {
        return price;
    }
    float setPrice (float p) {
        price = p;
    }
};

template <typename Coll>
void printItems (const std::string& msg, const Coll& coll)
{
    std::cout << msg << std::endl;
    for (const auto& elem : coll) {
        std::cout << ' ' << elem->getName() << ": "
                         << elem->getPrice() << std::endl;
    }
}

int main()
{
    using namespace std;

    // two different collections sharing Items
    typedef shared_ptr<Item> ItemPtr;
    set<ItemPtr> allItems;
    deque<ItemPtr> bestsellers;

    // insert objects into the collections
    // - bestsellers are in both collections
    bestsellers = { ItemPtr(new Item("Kong Yize",20.10)),
                    ItemPtr(new Item("A Midsummer Night's Dream",14.99)),
                    ItemPtr(new Item("The Maltese Falcon",9.88)) };
    allItems = { ItemPtr(new Item("Water",0.44)),
                 ItemPtr(new Item("Pizza",2.22)) };
    allItems.insert(bestsellers.begin(),bestsellers.end());

    // print contents of both collections
    printItems ("bestsellers:", bestsellers);
    printItems ("all:", allItems);
    cout << endl;

    // double price of bestsellers
    for_each (bestsellers.begin(), bestsellers.end(),
              [] (shared_ptr<Item>& elem) {
                  elem->setPrice(elem->getPrice() * 2);
              });
    
    // replace second bestseller by first item with name "Pizza"
    bestsellers[1] = *(find_if(allItems.begin(),allItems.end(),
                               [] (shared_ptr<Item> elem) {
                                   return elem->getName() == "Pizza";
                               }));

    // set price of first bestseller
    bestsellers[0]->setPrice(44.77);

    // print contents of both collections
    printItems ("bestsellers:", bestsellers);
    printItems ("all:", allItems);
}
What can auto be replaced with?

In your example, it seems it could be replaced by a std::shared_ptr<Item>.
--> for (const std::shared_ptr<Item>& elem : coll)

I tried Coll::iterator but that doesn't work.

I can’t see where you define Coll::iterator…
set<shared_ptr<Item>>
notice that you will be comparing memory address there, losing the efficient search of the bst
perhaps you want a custom comparator on the `name'
I don't know what to use instead of auto. Is it even possible to use something instead of auto?

1
2
3
4
5
6
7
8
9
template <typename Coll>
void printItems (const std::string& msg, const Coll& coll)
{
    std::cout << msg << std::endl;
    for (const auto& elem : coll) {
        std::cout << ' ' << elem->getName() << ": "
                         << elem->getPrice() << std::endl;
    }
}


1
2
3
4
    // two different collections sharing Items
    typedef shared_ptr<Item> ItemPtr;
    set<ItemPtr> allItems;
    deque<ItemPtr> bestsellers;
Two options.

The first is to use typename Coll::value_type instead of auto. (I'm pretty sure typename is required here).

The second is to modify the loop a little bit and use iterators.

1
2
3
4
for (Coll::iterator it = coll.begin(), it != coll.end(); coll++) {
        std::cout << ' ' << (*it)->getName() << ": "
                         << (*it)->getPrice() << std::endl;
}
I don't know what to use instead of auto. Is it even possible to use something instead of auto?

First, why are you worried about using something instead of auto? Second read Enoizat answer above.

Edit: By the way using auto in this case will probably be much less error prone.

Third, of course it is possible to use something instead of auto, if the compiler can deduce the type it can be done manually. Remember that auto is deducing the Type that the container is holding. In this case a single ItemPtr (std::shared_ptr<item>).



Last edited on
I just wanna know just to know :|

this doesn't work(it works as auto though):
1
2
3
4
for (Coll::iterator it = coll.begin(), it != coll.end(); coll++) {
        std::cout << ' ' << (*it)->getName() << ": "
                         << (*it)->getPrice() << std::endl;
}
Why doesn't it work? What are the exact error messages (all of them)?
1
2
3
4
5
 
for (Coll::iterator it = coll.begin(), it != coll.end(); coll++) {
        std::cout << ' ' << (*it)->getName() << ": "
                         << (*it)->getPrice() << std::endl;
}


 
Error	C2760	syntax error: unexpected token 'identifier', expected ';'


1
2
3
4
5
 
for (Coll::iterator it = coll.begin(), it != coll.end(); it++) {
        std::cout << ' ' << (*it)->getName() << ": "
                         << (*it)->getPrice() << std::endl;
}


 
Error	C2760	syntax error: unexpected token 'identifier', expected ';'


doug appears to have typo'd a comma where there should have been a semicolon. Try replacing the comma in the for loop's condition with a semicolon.

-Albatross
same result

1
2
3
4
for (Coll::iterator it = coll.begin(); it != coll.end(); it++) {
        std::cout << ' ' << (*it)->getName() << ": "
            << (*it)->getPrice() << std::endl;
    }


Error C2760 syntax error: unexpected token 'identifier', expected ';'
The error is in a different line. The compiler ran into the word "identifier" in the code. that word does not appear in any of your code snippets.

p.s. sorry about the semicolon typo.
Last edited on
no problem.

it runs when i do for (auto it = coll.begin(); it != coll.end(); it++)
but not for for (Coll::iterator it = coll.begin(); it != coll.end(); it++)
i get this error: Error C2760 syntax error: unexpected token 'identifier', expected ';'
Last edited on
Oh, I had to go back a number of posts to see that coll is of type const Coll&. With a const container you need to use Coll::const_iterator.

We're getting there.

BTW, as @jlb posted earlier, auto is a whole lot cleaner and safer. I understand you are just curious, but I hope this exercise shows you why auto was introduced.
I understand.

1
2
3
4
5
for (Coll::const_iterator it = coll.begin(); it != coll.end(); it++) 
{
        std::cout << ' ' << (*it)->getName() << ": "
            << (*it)->getPrice() << std::endl;
    }

i get this error: Error C2760 syntax error: unexpected token 'identifier', expected ';'

1
2
3
4
5
for (Coll::const_iterator it = coll.cbegin(); it != coll.cend(); it++) 
{
        std::cout << ' ' << (*it)->getName() << ": "
            << (*it)->getPrice() << std::endl;
    }

i get this error: Error C2760 syntax error: unexpected token 'identifier', expected ';'
Last edited on
it's for (typename Coll::const_iterator it...
hah thanks that worked
Using auto isn't just less error prone, it's much more flexible. For example, with auto, you can pass an array, but with Coll::const_iterator, you can't:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
 * by Nicolai M. Josuttis, Addison-Wesley, 2012
 *
 * (C) Copyright Nicolai M. Josuttis 2012.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <string>
#include <set>
#include <deque>
#include <algorithm>
#include <memory>

class Item {
  private:
    std::string name;
    float  price;
  public:
    Item (const std::string& n, float p = 0) : name(n), price(p) {
    }
    std::string getName () const {
        return name;
    }
    void setName (const std::string& n) {
        name = n;
    }
    float getPrice () const {
        return price;
    }
    void setPrice (float p) {
        price = p;
    }
};

template <typename Coll>
void printItems (const std::string& msg, const Coll& coll)
{
    std::cout << msg << std::endl;
    for (const auto& elem : coll) {
        std::cout << ' ' << elem->getName() << ": "
                         << elem->getPrice() << std::endl;
    }
}

int main()
{
    using namespace std;

    // two different collections sharing Items
    typedef shared_ptr<Item> ItemPtr;
    set<ItemPtr> allItems;
    deque<ItemPtr> bestsellers;
    ItemPtr arr[2];

    // insert objects into the collections
    // - bestsellers are in both collections
    bestsellers = { ItemPtr(new Item("Kong Yize",20.10)),
                    ItemPtr(new Item("A Midsummer Night's Dream",14.99)),
                    ItemPtr(new Item("The Maltese Falcon",9.88)) };
    allItems = { ItemPtr(new Item("Water",0.44)),
                 ItemPtr(new Item("Pizza",2.22)) };
    allItems.insert(bestsellers.begin(),bestsellers.end());

    arr[0] = ItemPtr(new Item("Banana", 1.5));
    arr[1] = ItemPtr(new Item("Bread", 2.0));
    
    // print contents of both collections
    printItems ("bestsellers:", bestsellers);
    printItems ("all:", allItems);
    printItems ("with array", arr);
    cout << endl;
}

Topic archived. No new replies allowed.