[ SpreX @ 19.06.2011. 13:22 ] @
Code:

#include <iostream>
#include <string>
#include <map>
using namespace std;

class Student
{
public:
    Student();
    Student(const string& name, const int age);
    Student(const Student& rhs);
    ~Student() {}
    
    void SetName(const string& name) { itsName=name; }
    string GetName() const { return itsName; }
    void SetAge(const int age) { itsAge=age; }
    int GetAge() const { return itsAge; }
    
    Student& operator=(const Student& rhs);
    
private:
    string itsName;
    int itsAge;
};

Student::Student():
itsName("Novi djak"), itsAge(16)
{}

Student::Student(const string& name, const int age):
itsName(name), itsAge(age)
{}

Student::Student(const Student& rhs):
itsName(rhs.GetName()), itsAge(rhs.GetAge())
{}

Student& Student::operator=(const Student& rhs)
{
    itsName=rhs.GetName();
    itsAge=rhs.GetAge();
    return *this;
}

ostream& operator<<(ostream& os, const Student& rhs)
{
    os << rhs.GetName() << " ima " << rhs.GetAge() << " godina.\n";
    return os;
}

template <class T, class A>
void ShowMap(const map<T, A>& v);    //prikazuje svojstva kontejnerske klase map

typedef map<string, Student> SchoolClass;   // <kljuc=ime stud., vrednost=Stud.>


int main()
{
    Student Harry("Harry",18);
    Student Sally("Sally",15);
    Student Bill("Bill", 17);
    Student Peter("Peter", 16);
    
    SchoolClass MathClass;
    //map<string, Student> MathClass;
    
    //dodavanje clana kod "map" kontejnera
    //map_object[key_valye]=object_value;
    MathClass[Harry.GetName()]=Harry;
    MathClass[Sally.GetName()]=Sally;
    MathClass[Bill.GetName()]=Bill;
    MathClass[Peter.GetName()]=Peter;
    
    cout << "MathClass:\n";
    ShowMap(MathClass);
    
    cout << "Zna se da " << MathClass["Bill"].GetName() << " ima ";
    cout << MathClass["Bill"].GetAge() << " godina.\n";
    return 0;
}


//prikazuje svojstva kontejnerske klase map
template <class T, class A>
void ShowMap(const map<T, A>& v)
{
    for (map<string, Student>::const_iterator ci=v.begin(); ci!=v.end(); ++ci)
        cout << ci->first << ": " << ci->second << "\n";
    cout << endl;
}


Program od gore radi, medjutim kada u funkciji ShowMap zamenim
Code:

map<string, Student>::const_iterator

sa
Code:

map<T, A>::const_iterator

kako bi mogli i drugi tipovi da budu prihvaceni dobijam gresku
Code:

lst19_10_Kontejnerska_klasa_map.cxx: In function ‘void ShowMap(const std::map<T, A, std::less<_Key>, std::allocator<std::pair<const _Key, _Tp> > >&)’:
lst19_10_Kontejnerska_klasa_map.cxx:90: error: expected ‘;’ before ‘ci’
lst19_10_Kontejnerska_klasa_map.cxx:90: error: ‘ci’ was not declared in this scope
lst19_10_Kontejnerska_klasa_map.cxx: In function ‘void ShowMap(const std::map<T, A, std::less<_Key>, std::allocator<std::pair<const _Key, _Tp> > >&) [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, A = Student]’:
lst19_10_Kontejnerska_klasa_map.cxx:75:   instantiated from here
lst19_10_Kontejnerska_klasa_map.cxx:90: error: dependent-name ‘std::map::const_iterator’ is parsed as a non-type, but instantiation yields a type
lst19_10_Kontejnerska_klasa_map.cxx:90: note: say ‘typename std::map::const_iterator’ if a type is meant


Postoji li nacin da se to uradi i kako?
[ glorius @ 20.06.2011. 10:32 ] @
Ako pogledas error report (posebno sledece dve linije):

lst19_10_Kontejnerska_klasa_map.cxx:90: error: dependent-name ‘std::map::const_iterator’ is parsed as a non-type, but instantiation yields a type
lst19_10_Kontejnerska_klasa_map.cxx:90: note: say ‘typename std::map::const_iterator’ if a type is meant

mozes uociti da kompajler const_iterator ne vidi kao tip (a trebalo bi). Resenje je da explicitno naglasis da je const_iterator tip.

typename map<T, A>::const_iterator

Ovo nije problem sa map<string, Student>::const_iterator posto u ovom slucaju const_iterator ne zavisi od template parametara (tj. nije dependent-name - mozes malo da pogledas teoriju da bi bolje razumeo)

Funkcija ShowMap bi onda trebala da izgleda ovako:

Code:


template <class T, class A>
void ShowMap(const map<T, A>& v)
{
    for (typename map<T, A>::const_iterator ci=v.begin(); ci!=v.end(); ++ci)
        cout << ci->first << ": " << ci->second << "\n";
    cout << endl;
}


[ SpreX @ 20.06.2011. 12:17 ] @
Shvatio sam tu poruku o gresci (deo koji se odnosi na typename). ono sto ne znam je kakav tip uopste treba da stoji tu. rekao bih da je ci pokazivac po onome kako poziva first i second, a opet kad vidim ci.begin() to bi bio prvi clan u "map" zar ne? pre par primera koristio sam kontejner list i ista stvar je radila (takodje for petlja), zasto kod map nece? .
[ glorius @ 21.06.2011. 07:13 ] @
Nisam najbolje razumeo sta ti nije jasno. Preformulisi malo pitanje da bih ti preciznije odgovorio.
[ SpreX @ 21.06.2011. 22:51 ] @
Kada si rekao typename mislio sam da treba konkretno tip podatka a ne doslovno rec typename zato sam se zbunio.
Kad sam stavio
Code:

template <class T, class A>
void ShowMap(const map<T, A>& v)
{
    for (typename map<T, A>::const_iterator ci=v.begin(); ci!=v.end(); ++ci)
        cout << ci->first << ": " << ci->second << "\n";
    cout << endl;
}

sve radi bez problema.

Ono sto ne razumem je sledece:
Code:

#include <iostream>
#include <list>
using namespace std;

typedef list<int> IntegerList;

int main()
{
    IntegerList intList;
    
    for(int i=0;i<=10;i++)
        intList.push_back(i*2);
    
    for (IntegerList::const_iterator ci=intList.begin(); ci!=intList.end();++ci)
        cout << *ci << " ";
    
    return 0;
}


Dakle zasto ovo radi (list), a onaj prvi program (map) nije hteo prvobitno s obzirom da sam const_iterator na isti nacin upotrebio u for petljama?

Takodje si rekao da kompajler ne vidi const_iterator kao tip, ali trebao bi. Mozes li mi pojasniti zbog cega bi to moglo biti?