2016-08-03 32 views
-2

我有一個yaml-cpp,它總是轉換成std::string,有時也轉換成別的東西。例如,如果字符串實際上是"3.14",它也會轉換爲double。我首先想要嘗試int,然後double,然後bool,如果不起作用,請轉換爲std::string。好吧,讓我們這些窩try - catch ES:乘以嵌套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; 
    } 
    } 
} 

嗯,更深更深的嵌套告訴我,這是不寫代碼的最佳方式。

有關如何改進設計的建議嗎?平面嵌套肯定會被建議。

+0

不知道,但只是一個嘗試{}和catch(...)?然後通過一個函數檢查異常...像ExceptionStatement(Exception 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

嘗試其他方式輪:
轉換成一個字符串,然後嘗試布爾等單一的try-catch內
一切,而忽略例外。

+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;