在boost中有boost::Any为我们提供了类似java或.net中的object类型,boost::Any能够代表任意类型,实现任意类型的类型安全存储以及安全的取回,常用在将不同类型的对象存储在标准容器中
一 Boost::Any
很多时候我们想有一种可以代表任何类型的类型,比如像纯面向对象语言java或.net中的Object类型,但是对于C++本身并没有这样一个基类,所以我们如果要解决这类问题,首先我们考虑的是使用基类的指针,这能够解决以部分问题,但是更多的我们可以求助于void*,使用void*的缺点就是丢失了类型信息和缺乏类型安全。
幸好的是在boost中有boost::Any为我们提供了类似java或.net中的object类型,boost::Any能够代表任意类型,实现任意类型的类型安全存储以及安全的取回,常用在将不同类型的对象存储在标准容器中。
二 源码剖析
源码:

namespace boost
{
class bad_any_cast;
class any;
template<typename T> T any_cast(any &);
template<typename T> T any_cast(const any &);
template<typename ValueType> const ValueType * any_cast(const any *);
template<typename ValueType> ValueType * any_cast(any *);
}

Boost::Any的实现比较简单,Any拥有一个模版构造函数,这使他可以接受任何类型的对象。真正的变量内容被封装在嵌套类类型的成员变量中,并且在嵌套类中使用typeid来记录真正的类型信息。
1) any& swap(any& other);交换存在两个 any 对象中的值。
2) any& operator=(const any& other);如果any实例非空,则丢弃所存放的值,并存入other值的拷贝。
3)template<typename ValueType> any& operator=(const ValueType& value);如果any实例非空,则丢弃所存放的值,并存入 value 的一份拷贝,value可以是任意符合any要求的类型。
4) bool empty() const;给出any实例当前是否有值,不管是什么值。因而,当any持有一个指针时,即使该指针值为空,则 empty也返回 false 。
5) const std::type_info& type() const;给出所存值的类型。如果 any 为空,则类型为 void.
6) any_cast()将any类型转化为真实的类型,如果是指针返回的可能是空指针,如果非指针,则可能会抛出异常。
三 实例
1)简单实例以及调用常用的成员函数:
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "boost/any.hpp"

class A


{
public:
void some_function()

{
std::cout << "A::some_function()\n";
}
};
class B


{
public:
void some_function()

{
std::cout << "B::some_function()\n";
}
};

void print_any(boost::any& a)


{
if (A* pA=boost::any_cast<A>(&a))

{
pA->some_function();
}
else if (B* pB=boost::any_cast<B>(&a))

{
pB->some_function();
}
else

{
try

{
std::cout << boost::any_cast<std::string>(a) << '\n';
}
catch(boost::bad_any_cast&)

{
std::cout << "Oops!\n";
}
}
}

int main()


{
std::cout << "Example of using any.\n\n";
std::vector<boost::any> store_anything;
store_anything.push_back(A());
store_anything.push_back(B());
// 我们再来,再加一些别的东西
store_anything.push_back(std::string("This is fantastic! "));
store_anything.push_back(3);
store_anything.push_back(std::make_pair(true, 7.92));
std::for_each( store_anything.begin(), store_anything.end(), print_any);


std::cout << "Example of using any member functions\n\n";
boost::any a1(100);
boost::any a2(std::string("200"));
boost::any a3;
std::cout << "a3 is ";
if (!a3.empty())

{
std::cout << "not empty\n ";
}
std::cout << "empty\n";
a1.swap(a2);
try

{
std::string s=boost::any_cast<std::string>(a1);
std::cout << "a1 contains a string: " << s << "\n";
}
catch(boost::bad_any_cast& e)

{
std::cout << "I guess a1 doesn't contain a string!\n";
}
if (int* p=boost::any_cast<int>(&a2))

{
std::cout << "a2 seems to have swapped contents with a1: " << *p << "\n";
}
else

{
std::cout << "Nope, no int in a2\n";
}
if (typeid(int)==a2.type())

{
std::cout << "a2's type_info equals the type_info of int\n";
}

}
2)解决类似与map但是可以映射到各种不同的类型的问题:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/any.hpp"
class property


{
boost::any value_;
std::string name_;
public:
property(const std::string& name,const boost::any& value)

: name_(name),value_(value)
{}

std::string name() const
{ return name_; }

boost::any& value()
{ return value_; }
friend bool operator<(const property& lhs, const property& rhs)

{return lhs.name_<rhs.name_;}
};
void print_names(const property& p)


{
std::cout << p.name() << "\n";
}
int main()


{
std::cout << "Example of using any for storing properties.\n";
std::vector<property> properties;
properties.push_back( property("B", 30));
properties.push_back( property("A", std::string("Thirty something")));
properties.push_back(property("C", 3.1415));
std::sort(properties.begin(),properties.end());
std::for_each(properties.begin(), properties.end(), print_names);
std::cout << "\n";
std::cout << boost::any_cast<std::string>(properties[0].value()) << "\n";
std::cout << boost::any_cast<int>(properties[1].value()) << "\n";
std::cout << boost::any_cast<double>(properties[2].value()) << "\n";
}
四 注意
1)Any中如果是指针,要注意指针的最后的释放,最好使用shared_ptr来管理。
2)Any中如果是指针,如果Any.isempty()返回false,但是any所包含的指针仍可能是无效的。
3)Any中如果是指针,则在调用any_cast()转化的过程中不会抛出异常,但是如果是一般变量或引用的话,类型不正确会抛出boost::bad_any_cast异常。
五 参考
1)Beyond the C++ Standard Library: An Introduction to Boost
2)boost在线document
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具