Короче говоря: я написал шаблонную функцию, которая использует yaml-cpp
библиотека для разбора файла YAML. Этот файл содержит список параметров в определенном формате. Функция возвращает обязательный параметр произвольного типа (следовательно, шаблонный), как указано в аргументе имени параметра.
Функция работает отлично. Я использую его для получения некоторых параметров в main()
как это:
int main(int argc, char** argv)
{
const std::string config_file_path = "/home.net/aa17gil/test/test.yaml";
const std::string param_name = "trolley/lasers/laserHoriz/min_rate";
const std::string param_name2 = "software/nodes/slam_karto/max_allowed_load_ratio";
//const std::string param_name3 = "software/nodes/slam_karto/unwanted_topics";
double min_rate;
double ratio;
//const std::string blah = "wtf";
if (getParamFromConfigFile<double>(config_file_path, param_name, min_rate))
std::cout << "min_rate = " << min_rate << std::endl;
else
std::cout << "Could not read param from config file" << std::endl;
if (getParamFromConfigFile<double>(config_file_path, param_name2, ratio))
std::cout << "ratio = " << ratio << std::endl;
else
std::cout << "Could not read param2 from config file" << std::endl;
return EXIT_SUCCESS;
}
Все хорошо, пока я не раскомментирую инициализацию строки в строке 11 const std::string blah = "wtf";
или тот, что в строке 6. По какой-то ошеломляющей причине выполнение этого вызывает второй вызов функции getParamFromConfigFile()
вернуть ложь. Я попытался отладить это, но он работает нормально, когда я строю проект в режиме отладки. Проблема возникает только в режиме выпуска.
Функция getParamFromConfigFile()
как следует:
template <typename T>
bool getParamFromConfigFile(const std::string& config_file_path, const std::string& param_name, T& param_value)
{
YAML::Node node = YAML::LoadFile(config_file_path);
std::vector<std::string> split_name;
boost::split(split_name, param_name, boost::is_any_of("/"));
std::string key_str = split_name.back();
split_name.pop_back();
for(const std::string& str: split_name)
{
if (node.IsNull())
{
std::cout << "Node is null. This happened before dereferencing " << str << std::endl;
return false;
}
node = node[str];
}
if (!node.IsSequence())
{
std::cout << "Final nested map's value is not a sequence" << std::endl;
std::cout << "Is map? " << (node.IsMap() ? "YES" : "NO") << std::endl;
std::cout << "Is scalar? " << (node.IsScalar() ? "YES" : "NO") << std::endl;
std::cout << "Is null? " << (node.IsNull() ? "YES" : "NO") << std::endl;
std::cout << "Is defined? " << (node.IsDefined() ? "YES" : "NO") << std::endl;
return false;
}
for(YAML::Node element: node)
{
if (!element.IsMap())
{
std::cout << "Final entry is not a map!" << std::endl;
return false;
}
if (element.size() != 1)
{
std::cout << "Map has multiple entries" << std::endl;
return false;
}if (element.begin()->first.Type() != YAML::NodeType::Scalar)
{
std::cout << "Key entry has to be a scalar" << std::endl;
return false;
}
std::string key;
try
{
key = element.begin()->first.as<std::string>();
}
catch (const YAML::TypedBadConversion<std::string>& type_conversion_exception)
{
std::cout << "Error converting param key into string" << std::endl;
std::cout << type_conversion_exception.msg << std::endl;
}
try
{
if (key == key_str)
{
if (element.begin()->second.Type() != YAML::NodeType::Scalar)
{
std::cout << "Key has been found, but the associated value is not a scalar";
return false;
}
param_value = element.begin()->second.as<T>();
return true;
}
}
catch (const YAML::TypedBadConversion<T>& type_conversion_exception)
{
std::cout << "Error covnerting param value into specified data type" << std::endl;
std::cout << type_conversion_exception.msg << std::endl;
}
}
std::cout << "Map key was not found in the file" << std::endl;
return false;
}
И если это помогает, точная точка отказа — проверка if (!node.IsSequence())
, Это условие истинно, поэтому функция возвращает ложь.
Есть идеи, почему это происходит?
Задача ещё не решена.
Других решений пока нет …