Повысить исключение program_options, не заменяя% canonical_option% tag

Интегрировали это (версия 1.52.0) в мое приложение, но наткнулись на проблему, как описано выше.

В примере, приложенном к исключению, метод метода() всегда имеет тэг% canonical_option% intact и не заменяется моим именем параметра.

Я использую VS2008, отключил unicode (опция "none" ) и удалил все остальные файлы из моего проекта, это только этот код в файле main.cpp.

Или у меня все это неправильно, и есть что-то еще, что я должен вызывать для форматирования сообщения об исключении с правильным именем параметра?

#include <boost/program_options.hpp>

namespace po = boost::program_options;

using namespace std;

int main(int argc, char* argv[])
{

    try {

        po::options_description optionalParams("optional");

        optionalParams.add_options() 
            ("log_severity,l", po::value<int>()->required(), "Minimum severity logging level")
            ("log_file,g", po::value<string>(), "Full path to log file")
            ;

        po::variables_map optMap;

        po::parsed_options parsed = po::command_line_parser(argc, argv)
            .options(optionalParams)
            .allow_unregistered()
            .run();

        po::store(parsed, optMap);

        po::notify(optMap);

    }
    catch(po::error e)
    {
        cout << e.what();
        return 0;
    }

    return 0;
}

Ответ 1

Когда я снова смотрю на код, после правильного просмотра кода повышения, ответ становится более очевидным.

catch(po::error e)
{
    cout << e.what();
    return 0;
}

Должно быть

catch(po::error& e)
{
    cout << e.what();
    return 0;
}

Без ссылки мы получаем "срез объектов", который здесь хорошо объясняется:

Захват исключений по ссылке

Не используя ссылочное средство, мы теряем переопределенный метод "что", который заменяет шаблон.

Ответ 2

Я потратил час на отладку - это интересное поведение на самом деле - единственная проблема с вашим кодом, я думаю, это тот факт, что вы ловите po::error

catch(po::error e)
{
   cout << e.what() << std::endl;
    return 0;
}

Если вы измените улов, чтобы линия была выше этой

catch(po::required_option e)
{
   cout << e.what() << std::endl;
    return 0;
}

вы получите следующее сообщение об ошибке.

the option '--log_severity' is required but missing
Press any key to continue . . .

Итак, в основном это выглядит так, что замена делается только в производных исключениях.

Изменить:

После некоторого чтения вы можете поймать std::exception, и он выведет правильное сообщение, когда вы вызываете what(). Подробнее см. Ссылку ниже.

http://www.boost.org/doc/libs/1_52_0/libs/exception/doc/boost-exception.html

Я также обнаружил, что существует метод, который может помочь вам в диагностике того, что происходит, когда вызывается исключение:

#include <boost/exception/diagnostic_information.hpp>

...

catch(...)
{
    std::cerr << "Unhandled exception!" << std::endl <<
    boost::current_exception_diagnostic_information();
    return 0;
}

Измените программу, как указано выше, и напечатайте что-то вроде ниже:

Unhandled exception!
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: class boost::exception_detail::clone_impl<struct    
                               boost::exception_detail::error_info_injector<class 
                               boost::program_options::required_option> >
std::exception::what: the option '--log_severity' is required but missing
Press any key to continue . . .