将多个相同类型的boost :: error_infos添加到boost :: exception

Ale*_*ler 5 c++ boost exception

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将输出

[struct tag_info *] = 2

我了解为什么会这样,但希望将其输出

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

我当然可以用typedef infoas boost::error_info<struct tag_info, std::vector<std::string> >,然后std::vector在将所有信息累积到异常之前累加到其中,但这有两个缺点:
a)它涉及到std :: vector的复制
b)我需要在抛出前建立向量,即我不能简单地使用shift运算符添加更多信息。

因此,我现在正在寻找更好的解决方案,以将多个相同error_info类型的信息添加到异常中。


编辑:
我试图按照Josh Kelley在下面的评论和超载中的建议进行操作operator <<

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

那将输出

[struct tag_multiple_infos *] = 1 2

很好,但是我喜欢Pyotrs回答得更好,因为它对我来说看起来更自然,并且需要更少的代码。但是,如果我想info在多个捕获站点1中添加,则此解决方案将更适合,因为我不需要知道已经添加了多少个信息。

1 =将信息转换为异常,将其抛出,在其他地方捕获,将更多信息转换为异常,然后重新抛出。

Pio*_*ycz 3

只需使用两个标签:

struct tag_info1;
struct tag_info2;
typedef boost::error_info<tag_info1, std::string> info1;
typedef boost::error_info<tag_info2, std::string> info2;
Run Code Online (Sandbox Code Playgroud)

像这样使用:

    BOOST_THROW_EXCEPTION(myexception()
        << info1("1")
        << info2("2") );
Run Code Online (Sandbox Code Playgroud)

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

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") );
Run Code Online (Sandbox Code Playgroud)