problem z std::map

0

Hej, mam następujący problem. Mam kilka map o różnych kluczach i tych samych wartościach, np. map<int, MyClass>, map<double,MyClass>, map<string,MyClass> itd. Następnie chcę wykasować z wszystkich klas te wpisy, gdzie MyClass ma konkretną wartość.

  1. utworzyłem sobie szablon
    template <typename value="value">
    void removeFromMaps(std::map<int, value> * myMap, MyClass & myclass)
    {
    std::map<int, value>::iterator it; // ta linijka nie dziala
    (map)<int,value>::iterator it // tak tez nie dziala
    /
    reszta funkcji */
    }

main(){
map<int, MyClass> map1;
map<double, MyClass> map1;
MyClass myclass1, myclass2;
removeFromMaps(&map1, myclass);
removeFromMaps(&map2, myclass);
}

, ale już samo to się nie kompiluje. Nie wiem co robie zle i czy mozna to zrobic jakos lepiej?

  1. czy mozna stworzyc jakis zbior map rozniacych sie wartosciami, tak zeby ten zbior przeslac tylko raz do funkcji, ktora sobie ten zbior przeiteruje i dla kazdej mapy z tego zbioru wykona jakas czynnosc ?

Mam nadzieje, ze ktos zrozumie o co mi chodzi :)

Dzieki z gory

0
std::map<int, value>::iterator it; // ta linijka nie dziala

a.cpp:8:6: error: need 'typename' before 'std::map<int, value>::iterator' because 'std::map<int, value>' is a dependent scope

czy mozna stworzyc jakis zbior map rozniacych sie wartosciami, tak zeby ten zbior przeslac tylko raz do funkcji, ktora sobie ten zbior przeiteruje i dla kazdej mapy z tego zbioru wykona jakas czynnosc ?

może std::vector<std::map*>?

0

Azarien, dzieki za pomoc z tym bledem, faktycznie o to chodzilo.

Natomiast nie da sie zrobic (chyba) std::vectorstd::map*, tylko musi byc std::vector<std::map<key, value> * >, a u mnie typ value jest rozny, wiec do wektora nie wejdzie.

Jakies inne pomysly ?

0

W moje opinii twój problem polega na złym definiowaniu szablonu.
Napisałeś, że masz wiele mapy o tych samym typie wartości, ale o rożnych typach kluczy, więc szablon chyba powinien to odzwierciedlać?

template <typename keyType>
void removeFromMaps(std::map<keyType, MyClass> * myMap, MyClass & myclass)
{
    typename std::map<keyType, MyClass>::iterator it;

    /* reszta funkcji */
}

http://ideone.com/NqHS0w

0

std::vector<std::map<key, value> * >, a u mnie typ value jest rozny, wiec do wektora nie wejdzie.

Dlaczego miałby nie wejść?

0

Azarien, właśnie o to mi chodzi. Istnieje taka struktura danych( poza krotką), która pomieści mapy o różnych typach kluczy ?

MarekR22, mój błąd, już ta funkcja mi działa

0

@adrianek251, może przedstaw problem bardziej od kuchni. Całkiem możliwe że wytaczasz armatę na muchę.

0

@adrianek251 Mnie się udało takie coś wykombinować:

#include <vector>
#include <map>
#include <string>
#include <iostream>

class MyMap{

};

class OtherKey : public MyMap , public std::map<int,double>{

};
class OtherKey2 : public MyMap , public std::map<int,std::string>{

};

int main() {
    std::vector<MyMap *> mm;
    OtherKey oth1;
    OtherKey2 oth2;
    
    oth1.insert(std::pair<int,double>(5,5.0));
    oth1.insert(std::pair<int,double>(1345,9.67));
    
    oth2.insert(std::pair<int,std::string>(5,"ssss"));
    oth2.insert(std::pair<int,std::string>(657657,"aaaa"));
    
    mm.push_back(&oth1);
    mm.push_back(&oth2);

    //jeśli będziemy chcieli wydobyć wartości(castowanie w dół) Trzeba wiedzieć jaki dokładnie tkwi obiekt w wektorze    
    OtherKey * othh1 = (OtherKey*)(mm[0]);
    OtherKey2 * othh2 = (OtherKey2*)(mm[1]);
    
    for(std::map<int,double>::iterator it = othh1->begin(); it != othh1->end(); it++) {
        std::cout << it->second <<"\n";
    }
    std::cout <<"\n";
    for(std::map<int,std::string>::iterator it = othh2->begin(); it != othh2->end(); it++) {
        std::cout << it->second <<"\n";
    }

  
}
 

Kod jest troche wtfowy ale chyba łatwiejszego sposobu nie ma niż castowanie w dół(trza wiedzieć co tkwi w danym obiekcie). Próbowałem użyć dynamic_cast ale wywala jakieś błędy ,że typ nie polimorficzny a jak robię zwykłe rzutowanie to przechodzi. Jeśli chcesz z tego wtfa skorzystać to musisz wyprowadzić z klasy MyMap nową klasę i odziedziczyć dodatkowo mapę z twoim kluczem i wartością. Dzięki temu sposobowi można w pojemniku przechowywać dowolny rodzaj danych(bez względu na typ) Wystarczy ,że prowizorycznie wyprowadzimy z klasy bazowej MyMap.

0
#include <map>

union u
{
	int a;
	char b;
	double c;
	float d;
	short e;
};

struct ch
{
	char c[128];
};

int main()
{
	std::map<u, u> m;
	std::map<ch, ch> m2;
	return 0;
}

Ja bym raczej cos takiego proponowal.

0

Mam nadzieje że to jakieś realne zadanie a nie wydumane zadanko ze studiów, bo jest 23 i jestem po 10h pracy...

Pytanie jest trochę źle zadane przez co utrudnione zadanie.
Nie chodzi o wywołanie czegokolwiek na wszystkich mapach, tylko o proste wywołanie operacji na wszystkich podległych mapach.

Coś takiego powinno chyba pomóc:

#include <iostream>
#include <map>
 
using namespace std;
 
template <typename T>
class MultiMapa {
public:    
    typedef T ValueType;
    //lub: typedef std::shared_ptr<T> ValueType;
private:    
    std::map<int, ValueType> m_map1;
    std::map<string, ValueType> m_map2;
    //...
public:
    MultiMapa() {
        
    }
    
    void erase(ValueType value)
    {
        erase(m_map1, value);
        erase(m_map2, value);
    }
 
    template<class Map, typename ValueType>
    void erase(Map &map, ValueType value)
    {
        // implentacja dla konkretnej mapy
    }
 
};
 
int main() {
 
    MultiMapa<double> mapa;
    //...wypelnienie
    mapa.erase(2.0);
    return 0;
}

http://ideone.com/FUs8L8

0

autor za bardzo kombinuje.
Szablon jaki podałem w zupełności wystarczy. W końcu ile będzie miał tych map o różnych kluczach? Dwie? Trzy?
Wiec trzymanie tych map w jednej tablicy nie ma praktycznego sensu, zwłaszcza, że typ kluczy nie będzie zarządzany dynamicznie (gdyby tak było to trzeba by użyć jakiegoś typu wariant za klucz).

Jeśli się uprzeć to trzeba by zdefiniować interface z potrzebnymi bebechami i utworzyć szablon dziedziczący po map<klucz,cos> i implementujący ten interfejs. Wtedy można trzymać tablicę wskaźników na ten interfejs i będzie można zrobić dowolnego dziwoląga obsługującego każdą kombinację klucz-wartość.

0

...a potem i tak na końcu się okazuje że ktoś to już zrobił w Boost:

http://www.boost.org/doc/libs/1_52_0/libs/multi_index/doc/tutorial/index.html

0

do MarekR22 - tych map jest kilkanascie :), wiec musialem cos kombinowac.

vpiotr - podwojne dzieki. Najpierw za przyklad klasy MultiMap (faktycznie dziala i to tak jak chcialem), a potem za odnosnik do boosta (nia mam pojecia jak to przeoczylem). W kazdym razie jak zwykle boost zalatwia sprawe.

Temat mozna uznac za zamkniety, naprawde mi bardzo pomogliscie

PS to nie bylo zadanie ze studiow :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1