当尝试将文本解析为boost :: variant时,变量的值不会更改.解析器本身似乎工作正常,所以我的假设是我在使用变体代码做错了.
我正在使用boost 1.46.1并在 Visual Studio 2008中编译以下代码.
hkaiser指出,规则和语法模板参数不能是Variant但Variant().
这有点"进一步",因为我现在有一个编译错误boost_1_46_1\boost\variant\variant.hpp(1304).评论说:
// NOTE TO USER :
// Compile error here indicates that the given type is not
// unambiguously convertible to one of the variant's types
// (or that no conversion exists).
Run Code Online (Sandbox Code Playgroud)
所以表达式的属性显然(qi::double_ | +qi::char_)不是boost::variant<double, std::string>.但那又是什么呢?
使用typedef boost::variant<double, std::vector<char>> Variant;解析器的工作.但是,这不像std :: string那么容易使用......
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
int main()
{
namespace qi = boost::spirit::qi;
typedef …Run Code Online (Sandbox Code Playgroud) 我的目标是保证所有变种类型的单一存储:根据Boost :: variant的'never empty'保证,我们需要覆盖
boost::has_nothrow_copy每个有界类型.但稍后文档提到了一些内容'boost::blank',如果该类型被绑定,variant将设置该值而不是尝试不提供默认的副本构造函数.
不清楚的是,如果在有界类型列表中添加boost :: blank将避免覆盖/专门化has_nothrow_copy
其他类型的要求吗?
考虑:
typedef boost::variant<T0, ..., TN> variant_T_t;
typedef boost::variant<U0, ..., UN> variant_U_t;
...
typedef boost::variant<variant_T_t, variant_U_t, ...> variant_t;
Run Code Online (Sandbox Code Playgroud)
这将对我的类型可以保留的类型数量的限制扩展到pow(BOOST_VARIANT_LIMIT_TYPES, L),其中L是嵌套级别的数量。
这(在某种程度上)是可以接受的解决方案,还是只是一个不好的hack?有更好的解决方案吗?也许老式union的比较合适?
我有提升变体类型定义:
typedef boost::variant< bool, int, float, double> VariantType;
Run Code Online (Sandbox Code Playgroud)
我想对它实现加/减/乘/除动作.以Add class为例.问题是如果在VariantType中添加新类型,例如std :: string,则必须使用新类型更新Add类.
struct Add : public boost::static_visitor<VariantType> {
template <typename T>
T operator() (T a, T b) const {
return a + b;
}
float operator() (int a, float b) const {
return a + b;
}
float operator() (float a, int b) const {
return a + b;
}
double operator() (int a, double b) const {
return a + b;
}
double operator() (double a, int …Run Code Online (Sandbox Code Playgroud) 随着std::variant<int, bool>我可以调用std::get<0>(var)的变种来获取值,因为它是第一种类型- int.
我怎么能这样做boost::variant?boost::get<>似乎只支持按类型而不是索引获取,我发现文档很难理解.
那里,
我正在尝试将现有代码调整为boost :: variant.想法是使用boost :: variant作为异构向量.问题是代码的其余部分使用迭代器来访问向量的元素.有没有办法将boost :: variant与迭代器一起使用?
我试过了
typedef boost::variant<Foo, Bar> Variant;
std::vector<Variant> bag;
std::vector<Variant>::iterator it;
for(it= bag.begin(); it != bag.end(); ++it){
cout<<(*it)<<endl;
}
Run Code Online (Sandbox Code Playgroud)
但它没有用.
编辑:谢谢你的帮助!但是在我的设计中,我需要从列表中获取一个元素并将其传递给代码的其他部分(这可能是令人讨厌的,因为我正在使用GSL).使用迭代器的想法是我可以将迭代器传递给函数,该函数将对来自该特定元素的返回数据进行操作.我看不出如何使用for_each做到这一点.我需要做类似的事情:
for(it=list.begin(); it!=list.end();++it) {
for(it_2=list.begin(); it_2!=list.end();++it_2) {
if(it->property() != it_2->property()) {
result = operate(it,it_2);
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
下面的代码(改编自spirit qi mini_xml示例)无法编译.存在与brac具有递归属性的规则相关的错误boost::variant.
但是,所有注释掉的版本brac都会编译.
我非常好奇在这种情况下知道是什么让简单的字符串解析器如此特殊:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <string>
#include <vector>
namespace client
{
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct ast_node;
typedef boost::variant<
boost::recursive_wrapper<ast_node>,
std::string
> ast_branch;
struct ast_node
{
std::string text;
std::vector<ast_branch> children;
};
}
BOOST_FUSION_ADAPT_STRUCT(
client::ast_node,
(std::string, text)
(std::vector<client::ast_branch>, children)
)
namespace client
{
template …Run Code Online (Sandbox Code Playgroud) 我编写了一个带有bison的verilog解析器,并使用boost :: variant存储每个规则的每个变体的所有差异情况.我使用一个小例子,BNF表达式来显示我的数据结构:
expression :
primary
| expression + expression
primary :
(expression)
| number
Run Code Online (Sandbox Code Playgroud)
存储它的数据结构是:
typedef boost::variant<
std::shared_ptr<exp1>,
std::shared_ptr<exp2>,
> expression
typedef boost::variant<
std::shared_ptr<prim1>,
std::shared_ptr<prim2>,
> primary
Run Code Online (Sandbox Code Playgroud)
class exp1/2和prim1/2用于存储表达式和primary中的两个不同的case:
class exp1 : public BaseClass {
public :
std::shared_ptr<primary> mem1;
exp1(std::shared_ptr<primary> i1):
mem1(i1)
{}
}
Run Code Online (Sandbox Code Playgroud)
为简化起见,我只显示exp1,而exp2和prim1/2是相似的.在野牛文件中,规则及其操作如下所示:
expression :
primary {
$$= std::make_shared<expression>(std::make_shared<exp1>($1));
}
Run Code Online (Sandbox Code Playgroud)
这样的解决方案导致两个问题:
1编译是veeeeeeeeeeeery慢,用g ++ 4.8.4花费差不多1分钟
2运行时间不是很快
我有一个用ocaml和ocamlyacc编写的类似解析器,它支持非常优化的变量规范,并且用1秒编译,并且运行速度与上面提到的g ++版本非常相似.
我使用boost :: variant的风格有什么问题吗?
我使用构造函数接受shared_ptrs将所有变量更改为类:
class ComponentBase {
};
Class VariantBase{
};
class prim1;
class prim2;
class exp1;
class exp2; …Run Code Online (Sandbox Code Playgroud) 我明白这boost::variant是实现的
template <typename... Vs>
struct variant {
std::aligned_union<Vs...>::type buffer;
....
};
Run Code Online (Sandbox Code Playgroud)
我们如何operator<<为这样的结构创建一个这样的结构来打印存储在缓冲区中的类型转换并将其传递operator<<给cout?为此,我们需要知道缓冲区中存储的元素的类型吗?有没有办法知道这个?
此外,我正在寻找这种实现的解释,如果存在的话.不只是它存在以及如何使用它.
这是我的问题的第二部分,最初发布在这里。感谢@sehe的澄清和帮助。我最终得到了下面的代码,但是我无法弄清楚如何将其简化为具有变体和访问者的通用解决方案。帮助/建议,不胜感激。谢谢。
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <boost/format.hpp>
#include <boost/variant.hpp>
template <typename T> class A
{
public:
typename T L;
typename std::shared_ptr<T> Lptr;
using tlist = std::vector<std::shared_ptr<T>>;
A(std::string n = "") : _n(n){}
A(const A& another) : _n(another._n){};
A(A&& a) : _n(a._n){ _lst = std::move(another._lst); }
tlist &lst() { return _lst; }
void emplace_back(std::shared_ptr<T> wp) {
_lst.emplace_back(wp);
}
std::string n() const { return _n; }
private:
tlist _lst;
std::string _n;
};
/*
suppose …Run Code Online (Sandbox Code Playgroud) boost-variant ×10
c++ ×10
boost ×7
boost-spirit ×2
variant ×2
c++11 ×1
c++14 ×1
parsing ×1
templates ×1