2016-08-03 5 views
-2

У меня есть yaml-cpp, который всегда преобразуется в std::string, а иногда и во что-то другое. Например, если строка фактически равна "3.14", она также преобразуется в double. Сначала я хотел бы попробовать int, затем double, затем bool, и если это не сработает, конвертируйте в std::string. Хорошо, так что давайте гнездятся эти try - catch эс:Умножьте вложенные try-catch

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, тем глубже и глубже вложенность говорит мне, что это не самый лучший способ, чтобы написать этот код.

Любые предложения по улучшению дизайна здесь? Конечно, было бы предложено плоское гнездование.

+0

Не уверен, но только одна попытка {} и поймать (...)? Затем проверьте Exception с помощью функции ... Как ExceptionStatement (исключение e). –

ответ

4

Вы можете поместить его в функции как:

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

затем:

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

Попробуйте наоборот:
Преобразование в в строку, а затем попробовать BOOL и т.д.
Все в одной примерки поймать и игнорировать исключение.

+0

Хорошая идея, спасибо! –

1

Использование исключений для нормального потока управления считается плохой практикой. В этом случае метод as использует метод «YAML :: convert :: decode», чтобы попытаться преобразовать узел в запрошенный тип, возвращая false, если он сработает, а не выбрасывает исключение.

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; 

, которые могут быть упрощены до

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; 
Смежные вопросы