C++ boost::以下代码的任何替换
我希望摆脱对代码的boost依赖。我有以下结构构造。在代码中的另一个位置调用和使用此结构时,将使用任意_cast。我知道模板类可以做到这一点,但我发现编写这个模板很困难。-C++新手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
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::coutboost::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,恐怕你会