2011-02-06 15 views
5

私はPoco :: mapを持っています。私は反復してストリームに出力しようとしていますが、コンパイラエラーが発生しています。私のコードは以下の通りです:その行のPoco :: anyのstd :: mapを反復できません::

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:

私はテンプレートがタイプに対し、コンパイル時に(あることを理解)ランタイムがそうではないだろう作業。それを強調していただきありがとうございます。また、DynamicAnyHolderの実装を持つ型だけを受け入れるため、DynamicAnyは機能しません。理想的ではありません。私がタイプに課したい唯一のルールは、< <がオーバーロードされているということです。

以下は私が現在やっていることですが、ある程度は機能しますが、既知のタイプのみをダンプします。

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のような型に魔法のように変わることはありません。

私はポコライブラリを知らないが、おそらくあなたがうまくいけば、あなたが出力するstd::stringに格納された値を変換することができます彼らの他の任意のタイプ、DynamicAny(documentationを参照)を使用できます。

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

+1を。おそらく、C++テンプレートはコンパイル時のものであり、コンパイル時にはテンプレートパラメータを知っておく必要があるかもしれません。 OPが何が間違っているかを理解できなかったことを見て、これはOPへのニュースかもしれない。 – sellibitze

+0

"おそらく、C++テンプレートはコンパイル時のものであり、コンパイル時にテンプレートパラメータを知っておく必要があるかもしれません。"はい、これは完全に感謝します。 残念ながら、DynamicAnyはDynamicAnyHolderの実装があるものだけをサポートしているため、<<演算子がオーバーロードされているユーザータイプ(ベクトル、行列など)はサポートされませんが、可能であれば、DynamicAnyHolderImplをすべて拡張することを避けたいと考えています。 – memo

+0

@ Memo:残念ながら、フードの下での具体的なvalueholdingクラス(boost 'holder ')のみが保持された値を出力する方法を知っています。それは訪問者を受け入れる方法がないかもしれないので、唯一のオプションは値を出力するメソッドを追加するか、少なくとも 'to_string'メソッドです。 http://codepad.org/NICm5r2rは、 'boost :: anyx'メソッドを' to_string'メソッドに変更したものです( 'stringifier 'は補完可能ですが、 'boost :: lexical_cast'を使ったデフォルトの実装は'const char *'以外のすべての "cout-able"オブジェクトでうまくいくでしょう。 – UncleBens

関連する問題