2011-02-06 14 views
5

Mam std :: map of Poco :: Any, które próbuję iterować i wyprowadzać do strumienia, ale dostaję błąd kompilatora. Moje kodu jest poniżej:Nie można przejść do iteracji std :: mapa Poco :: Any

map<string, Poco::Any>::const_iterator it; 
map<string, Poco::Any>::const_iterator end = _map.end(); 
map<string, Poco::Any>::const_iterator begin = _map.begin(); 
for(it = begin; it != end; ++it) { 
    const std::type_info &type = it->second.type(); 

    // compile error here: 
    os << " " << it->first << " : " << Poco::RefAnyCast<type>(it->second) << endl; 
} 

2 błędy na tej linii:

'type' cannot appear in a constant-expression 
no matching function for call to 'RefAnyCast(Poco::Any&)' 

UPDATE:

Rozumiem, że szablony są kompilacji, natomiast typ() jest czas pracy, więc nie będzie praca. Dzięki za podkreślenie tego. Również DynamicAny nie będzie działać, ponieważ akceptuje tylko typy, które mają implementacje DynamicAnyHolder, a nie idealne. Jedyną regułą, którą chciałbym narzucić, jest to, że mają przeciążone < <.

Poniżej jest to, co obecnie robię, działa do pewnego stopnia, ale tylko zrzuca znane typy, co nie jest tym, czego szukam.

string toJson() const { 
    ostringstream os; 
    os << endl << "{" << endl; 
    map<string, Poco::Any>::const_iterator end = _map.end(); 
    map<string, Poco::Any>::const_iterator begin = _map.begin(); 
    for(map<string, Poco::Any>::const_iterator it = begin; it != end; ++it) { 
     const std::type_info &type = it->second.type(); 
     os << " " << it->first << " : "; 

     // ugly, is there a better way? 
     if(type == typeid(int)) os << Poco::RefAnyCast<int>(it->second); 
     else if(type == typeid(float)) os << Poco::RefAnyCast<float>(it->second); 
     else if(type == typeid(char)) os << Poco::RefAnyCast<char>(it->second); 
     else if(type == typeid(string)) os << Poco::RefAnyCast<string>(it->second); 
     else if(type == typeid(ofPoint)) os << Poco::RefAnyCast<ofPoint>(it->second); 
     else if(type == typeid(ofVec2f)) os << Poco::RefAnyCast<ofVec2f>(it->second); 
     else if(type == typeid(ofVec3f)) os << Poco::RefAnyCast<ofVec3f>(it->second); 
     //else if(type == typeid(ofDictionary)) os << Poco::RefAnyCast<ofDictionary>(it->second); 
     else os << "unknown type"; 

     os << endl; 
    } 
    os<< "}" << endl; 
    return os.str(); 
} 

Odpowiedz

7

Informacje o typie środowiska wykonawczego nie mogą być używane do tworzenia instancji szablonów. Instancja o numerze type_info, której wartość będzie znana tylko podczas uruchamiania programu, nie zmienia się magicznie w typ, taki jak int, lub struct FooBar, gdy kompilator kompiluje ten kod.

nie wiem bibliotekę Poco, ale być może można użyć innych swoich dowolnego typu, DynamicAny (patrz documentation), które miejmy nadzieję, pozwala na konwersję zapisaną wartość std::string do wyprowadzania:

os << " " << it->first << " : " << it->second.convert<std::string>() << endl; 
+3

+1 . Być może należy podkreślić, że szablony C++ są kompilacją, a parametry szablonów muszą być znane podczas kompilacji. Widząc, że PO nie może zrozumieć, co jest nie tak, może to być nowość w PO. – sellibitze

+0

"Być może należy podkreślić, że szablony C++ są kompilacją, a parametry szablonów muszą być znane podczas kompilacji". Tak, to jasne, doskonale dzięki. Niestety DynamicAny tak naprawdę nie obsługuje * Any * type, tylko te, dla których istnieje implementacja DynamicAnyHolder, więc nie będzie obsługiwać typów użytkownika (np. Wektorów, macierzy itp.), Które mają operatora przeciążonego, ale ja chciałbym, aby w miarę możliwości nie rozszerzano możliwości DynamicAnyHolderImpl. – memo

+0

@Memo: Niestety tylko konkretna klasa własności (w boost 'holder ') pod maską będzie wiedzieć, jak wypisać trzymaną wartość. Wygląda na to, że może nie być sposobu, aby ten zaakceptował odwiedzających, więc jedyną opcją może być dodanie do niej metody, która wyprowadza wartość lub przynajmniej metodę 'to_string'. http://codepad.org/NICm5r2r to po prostu 'boost :: any' zmodyfikowany tak, aby miał metodę' to_string' ('stringifier ' jest po to, aby dodać możliwość kostiumizacji, ale domyślna implementacja z 'boost :: lexical_cast' powinna być w porządku dla wszystkich "cout-able" obiektów z wyjątkiem 'const char *'. – UncleBens

Powiązane problemy