C++ boost::以下代码的任何替换

C++ boost::以下代码的任何替换,c++,templates,boost,casting,boost-any,C++,Templates,Boost,Casting,Boost Any,我希望摆脱对代码的boost依赖。我有以下结构构造。在代码中的另一个位置调用和使用此结构时,将使用任意_cast。我知道模板类可以做到这一点,但我发现编写这个模板很困难。-C++新手 struct Properties { public: Properties() {} Properties(const std::string &s, const boost::any & p) { name = s; value = p; } templat

我希望摆脱对代码的boost依赖。我有以下结构构造。在代码中的另一个位置调用和使用此结构时,将使用任意_cast。我知道模板类可以做到这一点,但我发现编写这个模板很困难。-C++新手
 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;
};
struct属性{
公众:
属性(){}
属性(常量std::string&s、常量boost::any&p){
name=s;
数值=p;
}
模板
属性(T n){
值=n;
}
任何价值;
std::字符串名;
};

boost::any
使用类型擦除来存储任何类型的对象,您可以在运行时为其分配不同类型的值。
any_cast
用于检索存储在
any
对象中的具有正确类型的原始值。例如,您当前的类允许您这样做

Properties p("int", 42);
std::cout << boost::any_cast<int>(p.value) << '\n';
p = Properties("string", std::string("hello"));
std::cout << boost::any_cast<std::string>(p.value) << '\n';
然而,我上面发布的代码现在是非法的

Properties<int> p("int", 42);
std::cout << p.value << '\n';
// p = Properties<std::string>("string", std::string("hello"));
// will not compile because Properties<int> and Properties<std::string> are
// distinct types 
属性p(“int”,42);

std::cout
boost::any
使用类型擦除来存储任何类型的对象,您可以在运行时为其分配不同类型的值。
any_cast
用于检索存储在
any
对象中的具有正确类型的原始值。例如,您当前的类允许您这样做

Properties p("int", 42);
std::cout << boost::any_cast<int>(p.value) << '\n';
p = Properties("string", std::string("hello"));
std::cout << boost::any_cast<std::string>(p.value) << '\n';
然而,我上面发布的代码现在是非法的

Properties<int> p("int", 42);
std::cout << p.value << '\n';
// p = Properties<std::string>("string", std::string("hello"));
// will not compile because Properties<int> and Properties<std::string> are
// distinct types 
属性p(“int”,42);

std::cout只是为了好玩,我想我应该创建一个极简主义的任何实现:

//////////////////////////////////////////
// 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();
}
//////////////////////////////////////////
//my_any.hpp
#包括
#包括
构造我的任何
{
my_any()=默认值;
模板my_any(T const&v):_存储(新存储(v)){}
my_any(my_any const&other):_storage(other._storage?std::move(other._storage->clone()):nullptr{}
无效交换(my_any&other){_storage.swap(other._storage);}
朋友无效交换(my_any&a,my_any&b){a.swap(b);};
my_any&operator=(my_any other){swap(other);返回*this;}
//todo移动语义
私人:
结构存储器_基{
虚拟std::unique_ptr clone()=0;
虚拟~storage_base()=默认值;
};
模板
结构存储:存储库{
T值;
显式存储(T const&v):值(v){}
std::unique_ptr clone(){返回std::unique_ptr(新存储(值));}
};
std::唯一的ptr存储;
模板朋友T&any_cast(my_any&);
模板朋友T const&any_cast(my_any const&);
};
模板T&any_cast(my_any&a){
if(auto p=dynamic_cast(a._storage.get()))
返回p->value;
其他的
抛出std::bad_cast();
}
模板T常量和任意常量(my_任意常量和a){
if(auto p=dynamic_cast(a._storage.get()))
返回p->value;
其他的
抛出std::bad_cast();
}
然后,您可以完全按照用例所示的方式使用它:

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";
}
struct属性{
公众:
属性(const std::string&s=“”,const my_any&p={})
:名称(s),值(p){}
模板属性(tn){value=n;}
std::字符串名;
我的爱没有任何价值;
};
#包括
#包括
typedef std::向量道具;
int main()
{
道具v;
v、 “拜拜”,42岁;
v、 向后安放(“向量”,v);

std::cout只是为了好玩,我想我应该创建一个极简主义的任何实现:

//////////////////////////////////////////
// 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();
}
//////////////////////////////////////////
//my_any.hpp
#包括
#包括
构造我的任何
{
my_any()=默认值;
模板my_any(T const&v):_存储(新存储(v)){}
my_any(my_any const&other):_storage(other._storage?std::move(other._storage->clone()):nullptr{}
无效交换(my_any&other){_storage.swap(other._storage);}
朋友无效交换(my_any&a,my_any&b){a.swap(b);};
my_any&operator=(my_any other){swap(other);返回*this;}
//todo移动语义
私人:
结构存储器_基{
虚拟std::unique_ptr clone()=0;
虚拟~storage_base()=默认值;
};
模板
结构存储:存储库{
T值;
显式存储(T const&v):值(v){}
std::unique_ptr clone(){返回std::unique_ptr(新存储(值));}
};
std::唯一的ptr存储;
模板朋友T&any_cast(my_any&);
模板朋友T const&any_cast(my_any const&);
};
模板T&any_cast(my_any&a){
if(auto p=dynamic_cast(a._storage.get()))
返回p->value;
其他的
抛出std::bad_cast();
}
模板T常量和任意常量(my_任意常量和a){
if(auto p=dynamic_cast(a._storage.get()))
返回p->value;
其他的
抛出std::bad_cast();
}
然后,您可以完全按照用例所示的方式使用它:

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";
}
struct属性{
公众:
属性(const std::string&s=“”,const my_any&p={})
:名称(s),值(p){}
模板属性(tn){value=n;}
std::字符串名;
我的爱没有任何价值;
};
#包括
#包括
typedef std::向量道具;
int main()
{
道具v;
v、 “拜拜”,42岁;
v、 向后安放(“向量”,v);

std::cout感谢您的回复。但是限制不好。程序使用一个变量:std::vector prop;BOOST用法的另一个实例是BOOST::any_cast(prop[i]->value);@user3204803,那么我恐怕你必须坚持使用
boost::any
或者自己动手。@user3204803我恐怕Jeffrey是对的;在这种情况下,自己动手几乎是唯一的选择。谢天谢地,
boost::any
实现起来相对简单,源代码(如果你去掉各种编译器解决方法和其他选项,它会比这个短很多)谢谢你的回答。但是限制是不好的。程序使用了一个变量:std::vector prop;BOOST用法的另一个实例是BOOST::any_cast(prop[i]->value);@user3204803,恐怕你会