Следующее сравнение не выполняется для ошибки, которая выводит «asio.misc» для errorCode.category (). Name () и «конец файла» для errorCode.message ()
Если он утверждает, что находится в категории asio.misc, то почему условие if (errorCode.category () == boost :: asio :: error :: misc_category) оценивается как ложное?
Поиск в Google (включая ответы здесь) говорит, что boost :: system :: error_code может иметь одинаковое значение в более чем одной категории, поэтому я предполагаю, что для получения правильного сообщения и значения мы должны сравнить boost :: system :: error_category а также boost :: system :: error_code :: value.
Как правильно сравнить категорию, если она не работает?
Код в вопросе:
//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
std::ostringstream debugMsg;
debugMsg << " Error Category: " << errorCode.category().name() << ". "<< " Error Message: " << errorCode.message() << ". ";
if( errorCode.category() == boost::asio::error::misc_category )
{
switch (errorCode.value())
{
case boost::asio::error::eof:
debugMsg << ". Server has disconnected.";
break;
case boost::asio::error::connection_refused:
debugMsg << ". Connection Refused";
break;
default:
debugMsg << ". Unknown Error.";
break;
}
}
else
{
debugMsg << ". Unknown Error category.";
}
return debugMsg.str();
}
РЕДАКТИРОВАТЬ:
В соответствии с https://theboostcpplibraries.com/boost.system а также Boost :: file_system: проверка кодов ошибок
Люди обычно и по ошибке пишут код, сравнивая только значение ошибки, а не категорию. Одно только значение ошибки не является уникальным и может встречаться в нескольких категориях. Пользователи также могут создавать свои собственные коды ошибок и категории. Следовательно, оба должны быть сопоставлены. Это, я полагаю, не влияет на большое количество приложений, потому что они в любом случае используют только одну функцию или библиотеку для ускорения своего проекта, и / или большинство кодов ошибок отображаются на коды ошибок Windows, которые сделали все возможное, чтобы не сталкиваются.
Мне пришлось сесть на другой компьютер, чтобы просмотреть список рассылки буста, так как моя работа блокирует практически все.
http://boost.2283326.n4.nabble.com/Compare-boost-system-error-category-td4692861.html#a4692869
Согласно парню из-за этого сравнение не удается, потому что библиотека boost статически связана, а boost :: system :: error_category :: operator == сравнивает адреса, поэтому LHS — это адрес в одной библиотеке, а RHS это адрес в другом. Они не будут равны, когда они ожидаются.
Использование адреса для оператора == кажется мне очень глупым шагом. Я буду продолжать разглагольствовать об этом в списке рассылки поддержки и редактировать здесь для других, если будут обнаружены какие-либо новые знания.
На данный момент я динамически связываю и использую форму
//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
std::ostringstream debugMsg;
debugMsg << " Error Category: " << errorCode.category().name() << ". "<< " Error Message: " << errorCode.message() << ". ";
// IMPORTANT - These comparisons only work if you dynamically link boost libraries
// Because boost chose to implement boost::system::error_category::operator == by comparing addresses
// The addresses are different in one library and the other when statically linking.
//
// We use make_error_code macro to make the correct category as well as error code value.
// Error code value is not unique and can be duplicated in more than one category.
if (errorCode == make_error_code(boost::asio::error::connection_refused))
{
debugMsg << ". Connection Refused";
}
else if (errorCode == make_error_code(boost::asio::error::eof))
{
debugMsg << ". Server has disconnected.";
}
else
{
debugMsg << ". boost::system::error_code has not been mapped to a meaningful message.";
}
return debugMsg.str();
}
однако, это не работает, когда я статически соединяюсь, чтобы повысить также. Если у кого-то есть еще какие-либо предложения о том, как нам правильно сравнить boost :: system :: error_code и получить ожидаемые результаты, давайте перейдем к сути.
Стандарт C ++ 11 подразумевает, что каждый экземпляр категории ошибок должен иметь
глобально уникальный адрес и сравнения равенства должны использовать это
адрес для сравнения. К сожалению, это не надежно в портативном
код, только Dinkumware STL реализует уникальность истинного адреса
где-нибудь в процессе, и это добавляет полный барьер памяти для достижения
то есть это дорого.
Качество реализации Boost такое же, как у libstdc ++ или libc ++,
Вы можете получить несколько экземпляров в определенных обстоятельствах и тех,
может иметь разные адреса.
В моем собственном коде я сначала делаю оператор сравнения, и если это не удается, я
сделать strcmp () с именем категории (). На сегодняшний день это меня не укусило.
Я лично считаю этот аспект категорий ошибок
Дефект в стандарте, как указано, вызывает не только заголовок
реализация, если вы хотите, чтобы она соответствовала, и даже это не
покрыть RTLD_LOCAL, что означает, что вам нужно вернуться к именованным общим
память или какой-то взломать.
Других решений пока нет …