提高::下面的code任何替换 [英] boost::any replacement for the code below

查看:114
本文介绍了提高::下面的code任何替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望得到我的code提振摆脱依赖。我有以下的结构构造。当调用,并使用这个结构在​​了code另一个地方使用的boost :: any_cast 。我知道一个模板类会做,但发现很难写这个模板。 - C ++新秀

 结构属性{
 上市:
 属性(){}
 属性(常量标准::字符串&放大器; S,常量的boost ::任何和放大器; P){
      名称= S;
      值= P;
 } 模板< typename的T>
 属性(T N){
      值= N;
 }
 提高::任何价值; 性病::字符串名称;
};


解决方案

只是为了好玩,我想我会创建一个最低限度的实现:

  ////////////////////////////////////// ////
// my_any.hpp
#包括LT&;内存和GT;
#包括LT&;&stdexcept GT;结构my_any
{
    my_any()=默认值;
    模板< typename的T> my_any(T const的&安培; V):_storage(新的存储< T>(V)){}
    my_any(my_any常量和放大器;其他):_storage(other._storage的std ::移动(other._storage->的clone()):nullptr){}    无效掉期(my_any&安培;其他){_storage.swap(other._storage); }
    朋友交换空间(my_any&放大器;一,my_any和b){a.swap(B); };
    my_any&安培;运算符=(my_any等){交换(其他);返回*这一点; }    // TODO移动语义
私人的:
    结构storage_base {
        虚拟的std ::的unique_ptr< storage_base>克隆()= 0;
        虚拟〜storage_base()=默认值;
    };
    模板< typename的T>
    结构存储:storage_base {
        的T值;
        明确的存储(T const的&放大器;ⅴ):值(v)的{}
        的std ::的unique_ptr< storage_base>克隆(){返回的std ::的unique_ptr< storage_base>(新的存储< T>(值)); }
    };
    的std ::的unique_ptr< storage_base> _存储;
    模板< typename的T>朋友T&安培; any_cast(my_any&安培);
    模板< typename的T>朋友ŧ常量和放大器; any_cast(my_any常量&安培);
};模板< typename的T>夯; any_cast(my_any&放大器;一个){
    如果(自动p值=的dynamic_cast< my_any ::存储< T> * GT;(a._storage.get()))
        返回P->价值;
    其他
        抛出std :: bad_cast();
}模板< typename的T> ŧ常量和放大器; any_cast(my_any常量&放大器;一个){
    如果(自动p值=的dynamic_cast< my_any ::存储< T>常量* GT;(a._storage.get()))
        返回P->价值;
    其他
        抛出std :: bad_cast();
}

您可以使用它precisely同样的方式为您的用例,表现为:

 结构属性{
    上市:
        属性(常量标准::字符串&安培; S =,常量my_any&安培; P = {})
            :姓名(或名称),价值(P){}        模板< typename的T>属性(T N){值= N; }        性病::字符串名称;
        my_any值;
};#包括LT&;矢量>
#包括LT&;&iostream的GT;的typedef的std ::矢量<性状>道具;诠释的main()
{
    道具伏;
    v.emplace_back(再见,42);
    v.emplace_back(载体,ⅴ);    性病::法院LT&;< v.size():&所述;&下; v.size()&所述;&下; \\ n;
    性病::法院LT&;< V [0]。价值:&所述;&下; any_cast&所述; INT>(五[0]。价值)所述;&下; \\ n;
    性病::法院LT&;< V [1] .value.size():&所述;&下; any_cast<道具及GT;(五[1] .value的).size()<< \\ n;    v [0]。价值= v的    尝试{
        性病::法院LT&;< V [0]。价值:&所述;&下; any_cast&所述; INT>(五[0]。价值)所述;&下; \\ n;
    }赶上(的std ::异常const的急症室)
    {
        性病::法院LT&;< e.what()&所述;&下; !异常捕获,OK \\ N的;
    }    性病::法院LT&;< V [0] .value.size():&所述;&下; any_cast<道具及GT;(五[0] .value的).size()<< \\ n;
}

请参阅输出 住在Coliru

I wish get rid of boost dependency on my code. I have the following struct construct. When calling and using this struct at another place in the code boost::any_cast is used. I know a template class would do it, but finding it hard to write this template. - C++ Rookie.

 struct Properties {
 public:
 Properties() {}
 Properties(const std::string &s, const boost::any & p) {
      name = s;
      value = p;
 }

 template <typename T>
 Properties(T n) {
      value = n;
 }
 boost::any value;

 std::string name;
};

解决方案

Just for fun, I thought I'd create a minimalist any implementation:

//////////////////////////////////////////
// my_any.hpp
#include <memory>
#include <stdexcept>

struct my_any
{
    my_any() = default;
    template <typename T> my_any(T const& v) : _storage(new storage<T>(v)) { }
    my_any(my_any const& other)              : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}

    void swap(my_any& other)               { _storage.swap(other._storage); }
    friend void swap(my_any& a, my_any& b) { a.swap(b); };
    my_any& operator=(my_any other)        { swap(other); return *this; }

    // todo move semantics
private:
    struct storage_base { 
        virtual std::unique_ptr<storage_base> clone() = 0;
        virtual ~storage_base() = default; 
    };
    template <typename T>
    struct storage : storage_base {
        T value;
        explicit storage(T const& v) : value(v) {}
        std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage<T>(value)); }
    };
    std::unique_ptr<storage_base> _storage;
    template<typename T> friend T      & any_cast(my_any      &);
    template<typename T> friend T const& any_cast(my_any const&);
};

template <typename T> T& any_cast(my_any& a) { 
    if (auto p = dynamic_cast<my_any::storage<T>*>(a._storage.get()))
        return p->value;
    else
        throw std::bad_cast();
}

template <typename T> T const& any_cast(my_any const& a) { 
    if (auto p = dynamic_cast<my_any::storage<T> const*>(a._storage.get()))
        return p->value;
    else
        throw std::bad_cast();
}

You can then use it precisely the same fashion as your use-cases showed:

struct Properties {
    public:
        Properties(const std::string &s="", const my_any& p={}) 
            : name(s), value(p) {}

        template <typename T> Properties(T n) { value = n; }

        std::string name;
        my_any value;
};

#include <vector>
#include <iostream>

typedef std::vector<Properties> Props;

int main()
{
    Props v;
    v.emplace_back("bye", 42);
    v.emplace_back("vector", v);

    std::cout << "v.size(): "          << v.size()                           << "\n";
    std::cout << "v[0].value: "        << any_cast<int>(v[0].value)          << "\n";
    std::cout << "v[1].value.size(): " << any_cast<Props>(v[1].value).size() << "\n";

    v[0].value = v;

    try {
        std::cout << "v[0].value: " << any_cast<int>(v[0].value) << "\n";
    } catch(std::exception const& e)
    {
        std::cout << e.what() << " exception caught, ok!\n";
    }

    std::cout << "v[0].value.size(): " << any_cast<Props>(v[0].value).size() << "\n";
}

See the output Live On Coliru

这篇关于提高::下面的code任何替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆