Nico Schlömer Nico Schlömer - 4 months ago 11
C++ Question

Multiply nested try-catch

I have a yaml-cpp which always converts into a

std::string
, and sometimes also into something else. For example, if the string actually is
"3.14"
, it would also convert into
double
. I'd first like to try
int
, then
double
, then
bool
, and if that doesn't work, convert to a
std::string
. Alright, so let's nest those
try
-
catch
es:



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, the deeper and deeper nesting tells me that this isn't the best way to write that code.

Any suggestions on how to improve the design here? Flat nesting would certainly be advised.

Answer

You may put it in a function like:

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

then:

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;
}
Comments