Невозможно перебрать std :: map of Poco :: Any - PullRequest
5 голосов
/ 06 февраля 2011

У меня есть std :: map of 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 ошибки в этой строке:

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

UPDATE:

Я понимаю, что шаблоны - это время компиляции, тогда как type () - это среда выполнения, поэтому работать не будет. Спасибо, что подчеркнули это. Также DynamicAny не будет работать, потому что он принимает только те типы, которые имеют реализации DynamicAnyHolder, а не идеальные. Единственное правило, которое я хотел бы навязать типам, это то, что они перегружены.

Ниже то, что я сейчас делаю, работает в некоторой степени, но только сбрасывает известные типы, а это не то, что мне нужно.

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();
}

1 Ответ

7 голосов
/ 06 февраля 2011

Информация о типе среды выполнения не может использоваться для создания экземпляров шаблонов. Экземпляр type_info, значение которого будет известно только при запуске программы, волшебным образом не превращается в тип, такой как int, std::string или struct FooBar, когда компилятор компилирует этот код.

Я не знаю библиотеку Poco, но, возможно, вы могли бы использовать их другой тип Any, DynamicAny (см. документация ), который, как мы надеемся, позволит вам преобразовать сохраненное значение в std::string для вывода:

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