将多个相同类型的boost::error_infos添加到boost::exception中
Adding several boost::error_infos of the same type to a 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;
}
}
这将输出
[struct tag_info*]=2
我理解为什么会出现这种情况,但我宁愿让它输出
[struct tag_info*]=1
[struct-tag_info*]=2
当然,我可以将info
类型定义为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;
}
}
这将输出
[struct-tag_multiple_infos*]=1 2
这很巧妙,但我更喜欢Pyotrs的答案,因为它对我来说更自然,需要更少的代码。然而,如果我想在多个catch sites1中添加info
,那么这个解决方案会更合适,因为我不需要知道我已经添加了多少信息。
1=即将信息转移到一个异常中,抛出它,在其他地方捕获它,将更多信息转移到它中,然后重新抛出。
只需使用两个标签:
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") );
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 使用Boost Interprocess创建托管共享内存需要很长时间
- Boost::posix_time::ptime舍入到给定的分钟数
- boost xml parsingl将xml的路径作为变量发送