12

已经将此(版本 1.52.0)集成到我的应用程序中,但偶然发现了上述问题。

在附加的示例中,异常 what() 方法始终具有完整的 %canonical_option% 标记,并且不会替换为我的选项名称。

我正在使用 VS2008,禁用了 unicode(选项“无”)并从我的项目中删除了所有其他文件,它只是 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;
}
4

2 回答 2

20

当我再次查看代码时,在正确浏览了 boost 代码后,答案变得更加明显。

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

应该

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

如果没有引用,我们会得到“对象切片”,这里解释得很好:

通过引用捕获异常

不使用引用意味着我们失去了覆盖模板替换的“what”方法。

于 2012-11-19T09:55:46.363 回答
3

我只花了一个小时调试这个 - 实际上这是一个有趣的行为 - 我认为你的代码的唯一问题是你正在捕捉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 . . .

所以基本上看起来替换只在派生的异常中完成。

编辑:

经过一番阅读,您实际上可以捕获 a 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 . . .
于 2012-11-16T17:47:04.017 回答