2016-08-03 30 views
-2

Ich habe eine yaml-cpp, die immer in eine std::string konvertiert, und manchmal auch in etwas anderes. Wenn die Zeichenfolge beispielsweise "3.14" lautet, wird sie auch in double konvertiert. Ich würde zuerst versuchen, int, dann double, dann bool, und wenn das nicht funktioniert, zu einem std::string konvertieren. Okay, also lassen Sie uns Nest diese try-catch es:Multiplizieren verschachtelten Versuch-fangen

try { 
    const int a = node.as<int>(); 
    std::cout << "int!" << a << std::endl; 
} catch (YAML::BadConversion) { 
    try { 
    const double a = node.as<double>(); 
    std::cout << "double!" << a << std::endl; 
    } catch (YAML::BadConversion) { 
    try { 
     const bool a = node.as<bool>(); 
     std::cout << "bool!" << a << std::endl; 
    } catch (YAML::BadConversion) { 
     const std::string a = node.as<std::string>(); 
     std::cout << "string!" << a << std::endl; 
    } 
    } 
} 

Hm, desto tiefer und tiefer Verschachtelung sagt mir, dass dies nicht der beste Weg, um diesen Code zu schreiben.

Haben Sie Vorschläge, wie Sie das Design hier verbessern können? Flaches Nisten wäre sicherlich ratsam.

+0

nicht sicher, aber nur ein try {} und catch (...)? Dann überprüfe Exception durch eine Funktion ... Wie ExceptionStatement (Exception e). –

Antwort

4

Sie können es in einer Funktion setzen wie:

template<typename N, typename T> 
bool tryParseNode(N& node, T& val) { 
    try { 
    val = node.as<T>(); 
    return true; 
    } catch (YAML::BadConversion) { 
    return false; 
    } 
} 

dann:

int a; 
double d; 
bool b; 
std::string s; 
if (tryParseNode(node, a) { 
    std::cout << "int!" << a << std::endl; 
} 
else if (tryParseNode(node, d) { 
    std::cout << "double!" << d << std::endl; 
} 
else if (tryParseNode(node, b) { 
    std::cout << "bool!" << b << std::endl; 
} 
else if (tryParseNode(node, s) { 
    std::cout << "string!" << s << std::endl; 
} 
2

andersrum Versuchen Runde:
in einen String konvertieren, dann versuchen Bool usw.
Alles in einem einzigen Try-Catch und die Ausnahme ignorieren.

+0

Schöne Idee, danke! –

1

Ausnahmen Verwendung für den normalen Kontrollfluss betrachtet schlechte Praxis. In diesem Fall verwendet die as-Methode die `YAML :: convert :: decode '-Methode, um zu versuchen, den Knoten in den angeforderten Typ zu konvertieren, der ein falsches Ergebnis liefert, wenn es fehlschlägt, anstatt eine Ausnahme auszulösen.

int anInt; 
double aDouble; 
bool aBool; 

if (YAML::convert <int>::decode (node, anInt)) 
    std::cout << "int!" << anInt << std::endl; 
else 
if (YAML::convert <double>::decode (node, aDouble)) 
    std::cout << "double!" << aDouble << std::endl; 
else 
if (YAML::convert <bool>::decode (node, aBool)) 
    std::cout << "double!" << aBool << std::endl; 
else 
    std::cout << "string!" << node.as <std::string>() << std::endl; 

, die weiter

vereinfacht werden könnte
template <typename value_type> 
std::optional <value_type> decode (YAML::Node const & Node) 
{ 
    value_type Value; 

    if (YAML::convert <value_type>::decode (node, Value)) 
     return { Value }; 
    else 
     return {}; 
} 

if (auto anInt = decode <int> (node)) 
    std::cout << "int!" << *anInt << std::endl; 
else 
if (auto aDouble = decode <double> (node)) 
    std::cout << "double!" << *aDouble << std::endl; 
else 
if (auto aBool = decode <bool> (node)) 
    std::cout << "double!" << *aBool << std::endl; 
else 
    std::cout << "string!" << node.as <std::string>() << std::endl;