2011-02-06 4 views
5

저는 Poco :: map을 가지고 있습니다. 반복하고 스트림으로 출력하려고하는데 컴파일러 오류가 발생합니다. 내 코드는 다음과 같습니다 : 그 라인에Poco :: Any의 std :: map을 반복 할 수 없습니다. 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 :

내가 템플릿 유형 반면, 컴파일 시간 (것으로 알고 있습니다) 런타임 그렇습니다은하지 않습니다 작업. 저 밑줄을 주셔서 고마워요. 또한 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(); 
} 

답변

7

런타임 유형 정보는 템플릿을 인스턴스화하는 데 사용할 수 없습니다. 프로그램을 실행할 때만 값을 알 수있는 type_info의 인스턴스는 컴파일러가이 코드를 컴파일 할 때 마술처럼 int, std::string 또는 struct FooBar과 같은 유형으로 변하지 않습니다.

, DynamicAny 잘하면 당신이 출력 std::string에 저장된 값을 변환 할 수 있습니다 것이다 (documentation 참조) 나는 마시고 라이브러리를 모르겠지만, 아마도 당신은 다른 모든 유형을 사용할 수

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

1 . 아마도 C++ 템플릿은 컴파일 타임이며 컴파일 타임에 템플릿 매개 변수를 알아야한다는 점을 강조해야합니다. OP가 무엇이 잘못되었는지를 알 수 없다는 것을 알게되면, 이것은 OP에 대한 뉴스 일 수 있습니다. – sellibitze

+0

"아마도 C++ 템플릿은 컴파일 타임이며 템플릿 매개 변수는 컴파일 타임에 알려야한다는 것을 강조해야합니다." 네, 이걸 완벽하게 고맙습니다. 불행히도 DynamicAny는 실제로 DynamicAnyHolder 구현이있는 * Any * 유형을 지원하지 않으므로 << 연산자가 오버로드 된 사용자 유형 (예 : 벡터, 행렬 등)을 지원하지 않지만 가능하다면 모든 것이 DynamicAnyHolderImpl을 확장하도록하지는 않을 것입니다. – memo

+0

@ Memo : 유감스럽게도, 후드 아래의 구체적인 valueholding 클래스 (boost 'holder ')만이 보유한 값을 출력하는 방법을 알 것입니다. 방문자를 받아 들일 수있는 방법이 없을 수도 있으므로 유일한 방법은 값을 출력하는 메서드를 추가하거나 적어도 "to_string"메서드를 추가하는 것입니다. http://codepad.org/NICm5r2r는 단지'boost :: any'가'to_string' 메소드를 갖도록 수정되었습니다 ('stringifier '는 costumization 가능성을 추가하기위한 것이지만'boost :: lexical_cast'를 사용하는 기본 구현은 'const char *'를 제외한 모든 "cout-able"객체에 대해 괜찮을 것이다. – UncleBens