Boost使用指南之Boost.Any

  • Post author:
  • Post category:其他


正如大家所知,在STL容器中我们只能包含一种特定数据类型或者对象类型。比如,我们不能创建一个同时包含整数类型int和字符串类型string的List容器。但是,如果能创建一个同时包含多种类型对象的List容器可以极大地方便开发者。怎么办!在我们走投无路的时候可以求助与Boost。果然,Boost已经为我们准备好了Any模块。让我们试试它的威力吧!

功能描述:

实现一个统一的数据类型boost::any,any类型可以代表任何数据类型。

实现自动安全的类型转换功能boost::any_cast。

实例:

下面的实例展示了boost::any和boost::any_cast的基本用法,实现了list容器包含不同数据类型的功能。

//
//  main.cpp
//  boost
//
//  Created by 刘 诚 on 15/2/8.
//  Copyright (c) 2015年 刘 诚. All rights reserved.
//
#include <list>
#include <string>
#include <iostream>
#include <boost/any.hpp>
using boost::any_cast;
typedef std::list<boost::any> many;

void append_int(many &values, int value) {
    boost::any to_append = value;
    values.push_back(to_append);
}

void append_string(many& values, const std::string & value) {
    values.push_back(value);
}

void append_char_ptr(many& values, const char * value) {
    values.push_back(value);
}

void append_any(many& values, const boost::any & value) {
    values.push_back(value);
}

void append_nothing(many& values) {
    values.push_back(boost::any());
}

bool is_empty(const boost::any& operand) {
    return operand.empty();
}

bool is_int(const boost::any& operand) {
    /*if(any_cast<int>(&operand)) {
        std::cout << *(any_cast<int>(&operand)) << std::endl;
        return true;
    }
    return false;*/
    return operand.type() == typeid(int);
}

bool is_char_ptr(const boost::any& operand) {
    /*try {
        any_cast<const char *>(operand);
        std::cout << any_cast<const char *>(operand) << std::endl;
        return true;
    }
    catch(const boost::bad_any_cast &) {
        return false;
    }*/
    return operand.type() == typeid(const char *);
}

bool is_string(const boost::any& operand) {
    /*if(any_cast<std::string>(&operand))
     {
     std::cout << *(any_cast<std::string>(&operand)) << std::endl;
     return true;
     }
     return false;*/
    return operand.type() == typeid(std::string);
}

void count_all(many& values, std::ostream& out) {
    out << "#int == " << std::count_if(values.begin(), values.end(), is_int) << std::endl;
    out << "#const char * == " << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
    out << "#string == "
    << std::count_if(values.begin(), values.end(), is_string) << std::endl;
}

int main() {

    many manyBoostAny;
    boost::any test_any_1;
    boost::any test_any_2;
    boost::any test_any_3;

    append_int(manyBoostAny, 1);
    append_int(manyBoostAny, 2);

    append_string(manyBoostAny, std::string("test_string_1"));
    append_string(manyBoostAny, std::string("test_string_2"));

    append_char_ptr(manyBoostAny, "test_const_char_1");
    append_char_ptr(manyBoostAny, "test_const_char_2");

    append_any(manyBoostAny, test_any_1);
    append_any(manyBoostAny, test_any_2);
    append_any(manyBoostAny, test_any_3);
    count_all(manyBoostAny,std::cout);
}

下面实例实现了一个键值对,并且该数值类型可以是任意数据类型。

struct property {
    property();
    property(const std::string &, const boost::any &);
    std::string name;
    boost::any value;
};

由此可见,通过使用Boost.Any我们可以让代码变得更加灵活,从而轻松满足需求。

欢迎大家关注我的微信订阅号-程序员从这里开始



版权声明:本文为u013651556原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。