如何使用boost库中的变体和任何内部工作?在我正在进行的项目中,我目前使用标记的联合.我想使用其他东西,因为C++中的联合不允许您使用带有构造函数,析构函数或重载赋值运算符的对象.
我查询了任何和变体的大小,并用它们做了一些实验.在我的平台中,variant采用其最长可能类型的大小加上8个字节:我认为我只是8字节的类型信息,其余的是存储值.另一方面,任何只需要8个字节.由于我在64位平台上,我猜任何只是一个指针.
怎么知道它有什么类型?Variant如何通过模板实现它的功能?在使用它们之前,我想更多地了解这些类.
我在Boost.Any和Boost.Variant之间选择时遇到了麻烦.
我什么时候应该使用每一个?
各有哪些优缺点?
我基本上希望从外部来源存储一些状态.
例如boost::function,几乎完全移动到std::function,同样是boost::shared_ptr
但我找不到std::any?是重命名还是根本没有以新标准放置?
我有一个Map std::map<std::string, boost::any>,来自boost::program_options包.现在我想打印该地图的内容:
for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
std::cerr << it->first << ": " << it->second << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这是不可能的,因为boost::any没有operator<<定义.
打印该地图最简单的方法是什么?
我可以为任何自动尝试将每个输出运算符定义为anyint,然后是double,然后是字符串等,每次忽略错误并尝试强制转换直到转换成功并且我可以打印为指定类型.
但是在Boost中应该有一个更简单的方法吗?我需要像反向的东西lexical_cast......
据我所知,没有序列化(boost::serialization实际上)支持boost::any占位符.
有人知道是否有办法序列化自定义boost::any实体?
这里的问题很明显:boost::any使用基于模板的占位符来存储对象并typeid检查是否boost::any_cast合适.
因此,有一个自定义抽象超类placeholder和基于自定义模板的派生类,它们通过以下方式创建:
template <T> custom_placeholder : public placeholder {
virtual std::type_info type() const { return typeid(T); }
virtual ...
};
Run Code Online (Sandbox Code Playgroud)
显然,即使考虑序列化这些东西,这也会带来一些麻烦.也许有人知道做这种序列化的一些技巧(当然还有正确的反序列化)?
谢谢
我有一张代表配置的地图.这是地图std::string和boost::any.
此映射在开始时初始化,我希望用户能够在命令行上覆盖这些选项.
我喜欢做的是使用该options_description::add_option()方法从此地图构建程序选项.但是,它需要一个模板参数,po::value<>而我只有boost::any.
到目前为止,我只是拥有代码的shell. m_Config代表我的配置类,并getTuples()返回一个std::map<std::string, Tuple>. TuplePair是一个typedef std::pair<std::string, Tuple>和Tuple包含boost::any我感兴趣的.
po::options_description desc;
std::for_each(m_Config.getTuples().begin(),
m_Config.getTuples().end(),
[&desc](const TuplePair& _pair)
{
// what goes here? :)
// desc.add_options() ( _pair.first, po::value<???>, "");
});
Run Code Online (Sandbox Code Playgroud)
有没有办法以这种方式构建它,还是我需要自己去做?
提前致谢!
我试图使用boost :: any来封装sqlite返回值.然后我试着写一个循环来打印这些.
我的第一个想法是做一些像:
for(boost::any field: row) {
switch(field.type()) {
case typeid(double):
double value = any_cast<double>(field);
...
break;
case typeid(other type):
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在对于有经验的程序员来说,显然这不起作用,因为typeid返回实例而不是数字id.经过一些研究,我认为我可能会尝试,typeid(...).hash_code()但这不足够constexpr合格(除了哈希冲突的危险).
if ... else ...迷宫更好的方法来处理基于他们的typeid的对象?hash_code不是const_expr?这是单独编译目标文件的结果吗?std::type_index?考虑到它只是提供了一些额外的运营商(<,<=,>,>=),为什么却无法其功能与整合std::type_info?我正在使用一个容器来保存指向任何内容的指针列表:
struct Example {
std::vector<boost::any> elements;
}
Run Code Online (Sandbox Code Playgroud)
要在此容器中插入元素,我编写了几个辅助函数(成员struct Example):
void add_any(boost::any& a) {
elements.push_back(a);
}
template<typename T>
void add_to_list(T& a) {
boost::any bany = &a;
add_any(bany);
}
Run Code Online (Sandbox Code Playgroud)
现在,我想仅在元素不存在时才插入元素.要做到这一点,我想我只需要调用search在elements与适当的比较器功能.但是,我不知道如何比较boost::any实例.
我的问题:
知道我的boost::any实例总是包含指向某事物的指针; 是否可以比较两个boost::any值?
更新
我感谢你的回答.我还设法以一种可能不安全的方式做到这一点:boost::unsafe_any_cast用来获取void**并比较底层指针.
目前,这工作正常.但是,我会感谢您的评论:也许这是一个很大的错误!
#include <boost/any.hpp>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool any_compare(const boost::any& a1, const boost::any& a2) {
cout << "compare " << *boost::unsafe_any_cast<void*>(&a1)
<< " with: …Run Code Online (Sandbox Code Playgroud) 如何从boost中将我自己的类对象插入到ptr_map中.对象是模板化的,所以我不能在地图中使用一些静态类型名称.所以我做了:
ptr_map<string, any> someMap;
Run Code Online (Sandbox Code Playgroud)
我的类继承了boost :: noncopyable.
someMap.insert("Test", new MyClass<SomeTemplate>());
Run Code Online (Sandbox Code Playgroud)
错误是:错误:no matching function for call to ‘boost::ptr_map.
UPD:我更喜欢做一些包装,不要使用boost :: any.所以:
class IWrapper { };
class MyClass : public IWrapper { };
ptr_map<string, IWrapper> someMap;
someMap.insert("Test", new MyClass<SomeTemplate>());
Run Code Online (Sandbox Code Playgroud)
为什么它不起作用(同样的错误)?我可以将继承的类传递给父接口.怎么了?
我有一个核心转储,我正在使用gdb查看核心转储.
我想知道是否有办法能够检查gdb中boost :: any值的值?
在核心,我有地址提升任何,所以我尝试将其转换为占位符,看看我是否可以检查价值,但我做不到.我知道boost的类型是unsigned long,所以有没有办法查看知道类型的任何值?
(gdb) print ('boost::any::placeholder')(*(('boost::any'*)0x00007f263fa27730).content)
warning: can't find linker symbol for virtual table for `boost::any::placeholder' value
warning: found `boost::any::holder<bool>::~holder()' instead
$129 = warning: can't find linker symbol for virtual table for `boost::any::placeholder' value
warning: found `boost::any::holder<bool>::~holder()' instead
warning: can't find linker symbol for virtual table for `boost::any::placeholder' value
warning: found `boost::any::holder<bool>::~holder()' instead
{
_vptr.placeholder = 0x7f2a9a662560
}
Run Code Online (Sandbox Code Playgroud)
任何有关此事的帮助将不胜感激.谢谢!