6.3 Any库
6.3.1 头文件
"boost/any.hpp"
类any允许对任意的类型进行类型安全的存储和检索。与无差别的类型不同,any类中保存了类型的信息,而且实际上还不允许在不知道正确类型的情况下去获取所存储的值。当然,如果要查询类型的信息和测试所保存的值的可选项,办法还是有的。但是最终,调用者还是必须知道any对象中所存储的值的确切类型,否则any类就拒绝访问。对any类来说,可以把它看作是一个上了锁的保险箱。没有匹配的钥匙,就不能进入其中。any类对它所存储的类型有以下要求:
● 可复制构造(CopyConstructible):它必须可以复制这个类型。
● 析构函数不抛出异常:就像所有的析构函数所应该的那样!
● 可赋值(Assignable):为了保证强异常安全(不符合可赋值要求的类型也可以用于any类,但没有强异常安全的保证)。
下面是any类的公共接口:
namespace boost {
class any {
public:
any();
any(const any&);
template<typename ValueType>
any(const ValueType&);
~any();
any& swap(any &);
any& operator=(const any&);
template<typename ValueType>
any& operator=(const ValueType&);
bool empty() const;
const std::type_info& type() const;
};
}
6.3.2 成员
any();
该默认构造函数创建一个any类的空实例,即一个不含有值的any类。当然,也就无法从一个空的any类中检索值,因为它里面没有值存在。
any(const any& other);
该构造函数创建一个已有的any对象的独特副本。其中other中所包含的值被复制并存储到this中。
template<typename ValueType> any(const ValueType&);
这个模板化的构造函数存储传递给构造函数的类型为ValueType的参数的一份副本。其中参数是一个const引用,因此传递一个临时对象以存储到any中是合法的。这里需要注意的是,该构造函数不是显式的;如果是显式的,那么any就会难以使用,而且还会影响额外的安全性。
~any();
该析构函数销毁any类所包含的值,但是请注意,因为裸指针(raw pointer)的析构并不会对指针调用运算符delete或者运算符delete[],所以在any中使用指针时,应该把裸指针包装在一个诸如shared_ptr(请参阅第1章“Smart_ptr库”)的智能指针中。
any& swap(any& other);
交换两个any对象中所存储的值。
any& operator=(const any& other);
如果any的实例是非空的,那么该函数会丢弃所存储的值,然后存入other值的一份副本。
template<typename ValueType>
any& operator=(const ValueType& value);
如果any的实例是非空的,那么该函数会丢弃所存储的值,然后存入value的一份副本,其中value可以是符合any要求的任意类型。
bool empty() const;
该函数指示any的实例当前是否包含值,但不用考虑值的类型。因此,当any中存放有指针时,即使该指针值为空,empty函数也要返回false。
const std::type_info& type() const;
该函数指示any对象中所存储值的类型。如果any对象为空,则该函数返回的类型为void。
6.3.3 自由函数
template<typename ValueType>
ValueType any_cast(const any& operand);
any_cast函数允许访问any中所存储的值。其参数为要检索其中的值的any对象。如果类型ValueType与所存储值的类型不符,则抛出一个类型为bad_any_cast的异常。这里需要注意的是,该函数的语法和dynamic_cast函数的语法相似。
template<typename ValueType>
const ValueType* any_cast(const any* operand);
any_cast函数的重载,其参数为any对象的指针,它返回的是一个指向所存储值的指针。如果any对象中的类型不是ValueType,那么该重载函数将返回一个空指针。这里需要注意的是,该重载函数的语法仍然和dynamic_cast函数的语法相似。
template<typename ValueType>
ValueType* any_cast(any* operand);
any_cast函数的另一个重载,它与前一个重载版本相似,但前一个版本的参数类型和返回类型都使用了const限定的指针,而这个重载版本则不是这样的。
6.3.4 异常
bad_any_cast
当试图将any对象转型为该对象所存储类型以外的其他类型时,将抛出该异常。bad_any_cast异常派生自std::bad_cast。这里需要注意的是,当使用指针参数调用any_cast函数时,不会抛出异常(类似于使用指针类型调用dynamic_cast函数返回空指针);但是,当使用引用类型调用any_cast函数时,则会在失败时抛出异常。






