boost-数据类型之any与variant

Posted 一点一滴成长

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了boost-数据类型之any与variant相关的知识,希望对你有一定的参考价值。

1、any

  any可以存储任意类型元素,如int、double、string、vector或自定义类型。它能够存储任意类型的原因是其构造函数和赋值函数opeartor=是模板函数,可以接收任意类型。any不是一个模板类,所以定义元素的时候不必使用<>,如any a = 10;
  需要注意的有两点:
  在any存储字符串的时候只能使用string,如any a = string("hello");,不能使用C字符串,如:any a = "hello";
  如果保存动态内存指针类型,会引起内存泄露,解决方法是使用智能指针shared_ptr来指向动态内存,如:shared_ptr<char> ptrSmart(new char[10]); any a = ptrSmart;

  c++11中的auto类似any,eg:

  auto num = 10;
  map<int, float> vc1;
  auto iter = vc1.begin(); //相当于map<int, float>::iterator iter = vc1.begin();

  any的出现让C++仿佛变成了一种弱类型的动态语言。
  动态语言:运行期间才做数据类型检查的语言,即编译的时候不知道每一个变量的类型,如php、Ruby
  静态语言:编译期间做数据类型检查的语言,即编译的时候就知道每一个变量的类型,如C/C++、C#、JAVA
  强类型:变量一定是有类型的, 且变量/对象的类型一旦确定, 其类型不再允许更改,如C/C++/Java/C#
  弱类型: 变量的类型概念很弱或者没有类型的概念, 不同变量的类型可以更改. 如php、Ruby
  类型安全:的代码不会试图访问自己没被授权的内存区域,如C/C++就不是类型安全的,两个不同类型的指针之间可以通过dynamic_cast进行转换。

  

  any成员函数和能够操作any的函数:
  any::empty()判断any是否为空
  any_cast<>()获得any内部对象值或内部对象指针或内部对象的引用
  any::type()获得内部对象的类型,是一个标准type_info类的引用
  opeartor= 赋值
  swap()互换两个any
  .......

#include "stdafx.h"
#include "iostream"
using std::cout;
using std::endl;

#include "boost/any.hpp"
#include "boost/assert.hpp"
using namespace boost;

//判断any内部元素的类型
template <typename T> bool match_type(any& a)
{
    if (a.empty())
        return false;

    return typeid(T) == a.type();
}

//获得any内部值
template<typename T> T get_value(any& a)
{
    BOOST_ASSERT(match_type<T>(a));

    return any_cast<T>(a);
}

//获得any内部值的指针
template <typename T> T* get_pointer(any& a)
{
    BOOST_ASSERT(match_type<T>(a));

    return any_cast<T>(&a);
}

//获得any内部值的引用(引用可以被当做左值来使用)
template <typename T> T& get_reference(any& a)
{
    BOOST_ASSERT(match_type<T>(a));
    
    return any_cast<int&>(a);//获得a内部值的引用
    //return *any_cast<T>(&a);//*运算获得的是变量的引用,所以可以当做左值来使用
}

int main()
{
    any a = 10;

    int iNum = get_value<int>(a);//获得a的内部元素
    cout << iNum << endl;

    int * p = get_pointer<int>(a);//获得a内部元素的指针
    cout << *p << endl;

    get_reference<int>(a) = 5;//获得a内部元素引用,引用可以被当做左值来使用
    cout << *p << endl;

    if (match_type<int>(a))//判断a内部元素类型是否为int
        cout << "true" << endl;
    
    return 0;
}

2、variant

  variant是一种增强的union,C/C++中union只能持有POD(普通数据类型),而不能持有如string、vector等复杂类型,boost的variant则没有这个限制。

以上是关于boost-数据类型之any与variant的主要内容,如果未能解决你的问题,请参考以下文章

boost::variant:递归向量类型的奇怪行为

(C++, boost::variant) boost 变体映射的数据类型并对其执行数学运算

使用 boost::variant 库制作地图。如何将事物存储和显示为正确的类型?

为啥我不能用 boost::variant 访问这个自定义类型?

`boost::any` 和 `std::any` 之间的区别

如何返回由 boost::variant 返回类型中包含的类型的子集组成的 boost::variant