2016-03-20 7 views
1

Also mein Ziel ist es, eine Funktion oder Funktor, die verschiedene Werte zurückgeben können. Der Anwendungsfall besteht darin, Json-Objekte in den korrekten C++ - Typ zu konvertieren. Zum größten Teil habe ich das funktioniert, aber ich bin in Probleme mit Containern wie std::vector und geraten. Ich weiß, dass Sie eine Funktion nicht überladen können, um nur unterschiedliche Werttypen zurückzugeben, also habe ich eine struct mit Template-Spezialisierung verwendet. Ich dachte mir, ich müsste teilweise Template-Spezialisierung verwenden, um dies zu erreichen, aber ich bin auf Kompilierungsfehler stoßen. Hier ist, was mein Code wie folgt aussieht:Partielle C++ Template-Spezialisierung mit STL-Containern

template <typename T> 
struct from_json 
{ 
    T operator()(const Json::Value &json) 
    { 
     return T::fromJson(json); 
    } 
}; 

template <> 
struct from_json<std::string> 
{ 
    std::string operator()(const Json::Value &json) 
    { 
     return std::string(json.asCString()); 
    } 
}; 

template <typename T> 
struct from_json<std::vector<T> > 
{ 
    std::vector<T> operator()(const Json::Value &json) 
    { 
     std::vector<T> vector; 

     for (auto obj : json) 
      vector.push_back(from_json(obj)); 

     return vector; 
    } 
}; 

Einige Anmerkungen zum Code-Schnipsel: ich eine abstrakte Klasse, die fromJson erfordert von meinen eigenen serializable Klassen implementiert werden, das ist das, was der allgemeine Fall geht. Die std::string Generalisierung scheint gut zu funktionieren. Die std::vector ist, wo die Dinge brechen. Der Compiler erkennt, dass dies die Spezialisierung ist, die verwendet werden sollte, gibt aber einen Fehler, wenn er versucht, sie tatsächlich zu verwenden.

std::vector<std::string> my_vector = from_json<std::vector<std::string> >(json["my_vector"]); 

Der Compiler-Fehler ist folgende:

error: no matching function for call to 'from_json<std::vector<std::__cxx11::basic_string<char> > >::from_json(const Json::Value&)' 
std::vector<std::string> my_vector = from_json<std::vector<std::string> >(json["my_vector"]); 
note: candidate: constexpr from_json<std::vector<std::__cxx11::basic_string<char> > >::from_json() 

Es ist auch erwähnenswert, dass ich Vorschläge auf diesem C++ 11.

Ich bin auf jeden Fall offen bin mit besser getan werden könnte wenn es einen besseren Weg gibt.

Danke!

Antwort

2

So in dieser Zeile:

vector.push_back(from_json(obj)); 

from_json in Ihrem Code ist eine Klasse-Vorlage mit einer definierten operator(). Es ist keine Funktion oder ein Funktionsobjekt (in diesem Sinne ist es wie std::hash). So können Sie nicht aufrufen - Sie müssen eine Instanziierung davon aufrufen.

Ich vermute, Sie so etwas wie meine:

vector.push_back(from_json<T>{}(obj)); 

Oder wenn Sie in Entfernungs-v3 sind:

std::vector<T> operator()(const Json::Value &json) 
{ 
    return json | view::transform(from_json<T>{}); 
} 
+0

Wow ja ich auf der Instanz Sache vermasselt vollständig. Ich habe vergessen, die '{}' hinzuzufügen, um wie Sie vorgeschlagen zu instanziieren. Danke, dass du dieses raus zeigst! –

Verwandte Themen