加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 向boost :: exception添加几个相同类型的boost :: error_in

发布时间:2020-12-16 07:32:24 所属栏目:百科 来源:网络整理
导读:#include boost/exception/all.hpp#include iostreamstruct myexception : virtual boost::exception,virtual std::exception {};typedef boost::error_infostruct tag_info,std::string info;void main(){ try { BOOST_THROW_EXCEPTION(myexception() info(
#include <boost/exception/all.hpp>
#include <iostream>

struct myexception : virtual boost::exception,virtual std::exception {};
typedef boost::error_info<struct tag_info,std::string> info;

void main()
{
    try
    {
        BOOST_THROW_EXCEPTION(myexception()
            << info("1")
            << info("2") );
    }
    catch(const myexception& e)
    {
        std::cout << boost::diagnostic_information(e) << std::endl;
    }
}

这将输出

[struct tag_info *] = 2

我明白为什么会这样,但宁愿让它输出

[struct tag_info *] = 1
[struct tag_info *] = 2

当然,我可以将typedef info设置为boost :: error_info< struct tag_info,std :: vector< std :: string> >然后在将它转移到异常之前在std :: vector中累积所有信息,但这有两个缺点:
a)它涉及复制std :: vector
b)我需要在投掷之前建立向量,即我不能简单地使用移位运算符来添加更多信息.

因此,我现在正在寻找更好的解决方案,用于向异常添加几个相同error_info类型的信息.

编辑:
我尝试按照Josh Kelley在下面的评论中提出的那样做并重载运算符<<:

#include <boost/exception/all.hpp>
#include <iostream>
#include <vector>

typedef boost::error_info<struct tag_info,std::string> info;
typedef boost::error_info<struct tag_multiple_infos,std::vector<std::string> > multiple_infos;

struct myexception : virtual boost::exception,virtual std::exception
{
    myexception& operator<< (const info& rhs)
    {
        std::vector<std::string>* pinfos = boost::get_error_info<multiple_infos,myexception>(*this);
        if (pinfos != NULL)
        {
            pinfos->push_back(rhs.value());
        }
        else
        {
            std::vector<std::string> infos;
            infos.push_back(rhs.value());
            *this << multiple_infos(infos);
        }
        return *this;
    }
};

std::string to_string(const multiple_infos& info)
{
    std::ostringstream oss;
    std::for_each(info.value().begin(),info.value().end(),[&oss](const std::string& str) { oss << str << ' '; });
    return oss.str();
}

void main()
{
    try
    {
        BOOST_THROW_EXCEPTION(myexception()
            << info("1")
            << info("2") );
    }
    catch(const myexception& e)
    {
        std::cout << boost::diagnostic_information(e) << std::endl;
    }
}

这将输出

[struct tag_multiple_infos *] = 1 2

这很整洁,但我更喜欢Pyotrs的答案,因为它对我来说更自然,需要更少的代码.但是,如果我想在多个catch sites1中添加信息,那么这个解决方案会更合适,因为我不需要知道已经添加了多少个信息.

1 = I.e.将信息转换为异常,抛出它,将其捕获到其他地方,将更多信息转移到其中,然后重新抛出.

解决方法

只需使用两个标签:

struct tag_info1;
struct tag_info2;
typedef boost::error_info<tag_info1,std::string> info1;
typedef boost::error_info<tag_info2,std::string> info2;

使用这样:

BOOST_THROW_EXCEPTION(myexception()
        << info1("1")
        << info2("2") );

如果您想要更多信息,请使用模板:

template <unsigned N>
struct tag_info {};

template <unsigned N>
struct Nth {
  typedef boost::error_info<tag_info<N>,std::string> info;
};

    BOOST_THROW_EXCEPTION(myexception()
        << Nth<1>::info("1")
        << Nth<2>::info("2") );

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读