提高::下面的code任何替换 [英] boost::any replacement for the code below
本文介绍了提高::下面的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屋!
查看全文