【问题标题】:Boost program_options exception not replacing %canonical_option% tagBoost program_options 异常不替换 %canonical_option% 标记
【发布时间】:2012-11-16 14:58:15
【问题描述】:

已将此(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;
}

【问题讨论】:

    标签: c++ exception boost


    【解决方案1】:

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

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

    应该是

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

    没有参考,我们得到“对象切片”,这里解释得很好:

    Catching exceptions by reference

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

    【讨论】:

    • 大声笑 - 我太拘泥于细节,看不到这个 - :) 很高兴你把它整理好了
    【解决方案2】:

    我只花了一个小时调试这个 - 实际上这是一个有趣的行为 - 我认为你的代码的唯一问题是你正在捕捉 po::error

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

    如果你把 catch 改成上面的那一行

    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 . . .
    

    【讨论】:

    • 虽然没有找到问题的根本原因,但您的工作让我进入了正确的代码,揭示了真正的原因。感谢和感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2013-01-02
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多