此问题确定不可复制的类型不能与Boost变体一起使用
Tree 类
template <class T = int>
class Tree{
private:
class TreeNode{
public:
std::unique_ptr Nodes
Move constructors and move assignment + other public members
private:
TreeNode(const TreeNode &other); (= delete not supported on compiler)
TreeNode& operator=(const TreeNode &rhs); (= delete not supported on compiler)
}; // End Tree Node Class Definition
Tree(const Tree &other); (= delete not supported on compiler)
Tree& operator=(const Tree &rhs); (= delete not supported on compiler)
public:
Move constructors and move assignment + other public …Run Code Online (Sandbox Code Playgroud) 在面向对象的语言中,使用简单的层次结构(Composite模式)实现AST(抽象语法树)并通过访问者遍历它们是相当普遍的.
在函数式编程语言中,使用变量/和类型,然后使用模式匹配,是正确的方法.
C++同时具有继承和Boost.Variants.我已经使用继承编写了几个AST层次结构,但我想从那些使用变体方法的人那里得到一些反馈.我想知道哪一个是"最好的",在性能(时间和空间)方面,而且在可维护性(易于创建树和遍历它们)方面.
我对实现hash-consing(保留每个公共子树的单个副本)的经验特别感兴趣,可能还有Boost.Flyweight.
谢谢!
我有类似下面的代码.
typedef uint32_t IntType;
typedef IntType IntValue;
typedef boost::variant<IntValue, std::string> MsgValue;
MsgValue v;
Run Code Online (Sandbox Code Playgroud)
而不是说这个,
IntValue value = boost::apply_visitor(d_string_int_visitor(), v);
Run Code Online (Sandbox Code Playgroud)
我想传递一个额外的参数,如下所示:但是operator()给出了编译错误.
//This gives an error since the overload below doesn't work.
IntValue value = boost::apply_visitor(d_string_int_visitor(), v, anotherStr);
class d_string_int_visitor : public boost::static_visitor<IntType>
{
public:
inline IntType operator()(IntType i) const
{
return i;
}
inline IntValue operator()(const std::string& str) const noexcept
{
// code in here
}
//I want this, but compiler error.
inline IntValue operator()(const std::string& str, const std::string s) …Run Code Online (Sandbox Code Playgroud) 我有两个指针,只能设置其中一个,所以我正在考虑使用boost :: variant,比如说:boost::variant<shared_ptr<Type1> shared_ptr<Type2>>.类型1和类型2不同,但它们共享一些功能.例如,Thay都有这种方法IsUnique.
如果我有代码来检查初始化:
ASSERT(type1 != nullptr || type2 != nullptr);
ASSERT(type1 == nullptr || type2 == nullptr);
ASSERT(type1 == nullptr || type1->IsUnique());
ASSERT(type2 == nullptr || type2->IsUnique());
Run Code Online (Sandbox Code Playgroud)
我希望能够用尽可能接近的东西替换它:
ASSERT(variant != nullptr);
ASSERT(variant->IsUnique());
Run Code Online (Sandbox Code Playgroud)
但似乎我必须定义访问者,切换类型.
我是否会遗漏某些内容,是否有模板或某些内容可以让我将某些内容应用于当前类型的内容?它可能是c ++ 14.
我正在尝试使用Boost Spirit商店JSON对象将JSON字符串解析为递归数据结构:
Value <== [null, bool, long, double, std::string, Array, Object];
Array <== [Value, Value, Value, ...];
Object <== ["name1": Value, "name2": Value, ...];
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
#include <map>
#include <vector>
#include <string>
#include <boost/variant.hpp>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
struct JsonNull {};
struct JsonValue;
typedef std::map<std::string, JsonValue *> JsonObject;
typedef std::vector<JsonValue *> JsonArray;
struct JsonValue : boost::variant<JsonNull, bool, long, double, std::string, JsonArray, JsonObject>
{
};
JsonValue aval = JsonObject();
Run Code Online (Sandbox Code Playgroud)
编译时我得到错误:
Error C2440: 'initializing' : cannot convert from 'std::map<_Kty,_Ty>' to 'JsonValue'
Run Code Online (Sandbox Code Playgroud)
而且,如何安全地将JsonValue转换为JsonObject?当我尝试做:
boost::get<JsonObject>(aval) …Run Code Online (Sandbox Code Playgroud) 我已经尝试了几个小时来编写一个派生自的类boost::variant.但我不明白是什么问题(我不明白编译错误意味着什么).
实现干净boost::variant派生类的规则是什么?
#include <boost/variant.hpp>
class MyVariant : public boost::variant<char,bool>
{
public:
MyVariant () : boost::variant<char,bool>( ) {}
template <typename T>
MyVariant( T& v) : boost::variant<char,bool>(v) {}
template <typename T>
MyVariant(const T& v) : boost::variant<char,bool>(v) {}
};
int main ()
{
MyVariant a;
MyVariant b = a; //compilation error
// MyVariant c = MyVariant();
// MyVariant d (true);
// MyVariant e ('E');
}
Run Code Online (Sandbox Code Playgroud)
为什么我要使用继承?(编辑给@zaufi更多细节)
const char*为stringint为longenum …为什么以下打印出来"A boolean!"?我意识到有一些奇怪的转换,因为如果我显式构造一个std :: string,我会得到正确的行为.但是为什么visitor::operator()(bool)在下面的情况下选择重载决策呢?
#include <boost/variant.hpp>
#include <string>
typedef boost::variant<bool, std::string> type;
struct visitor : public boost::static_visitor<> {
void operator()(bool b) const {
std::cout << "A boolean!" << std::endl;
}
void operator()(const std::string& str) const {
std::cout << "A string!" << std::endl;
}
};
int main(int argc, char* argv[]) {
type t = "I am a string";
t.apply_visitor(visitor());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在运行Visual Studio 2012(CTP或者没有给出相同的结果)
我希望从boost变量中获取指向基类的指针,如果我将orignally指针放到派生类上.有没有办法实现这一点.以下代码不起作用.
class A{ public: virtual ~A(){}}; class B : public A{};
typedef boost::variant<A*,B*> MyVar;
MyVar var = new B;
A* a = boost::get<A*> (var); // the following line throws exception
Run Code Online (Sandbox Code Playgroud)
也许有人有想法怎么写我自己的get函数如果请求的类型是基类的存储类型的变种,这将考验,然后做相应的投
假设我有一个嵌套boost::variant类型TNested包含一些类型和一些其他boost::variant类型(它本身不能再包含boost::variant types,因此不会有递归).
我正在寻找一个模板别名flatten<TNested>,它将评估一个boost::variant没有嵌套boost::variant的类型,例如TFlatten,虽然可能的重复类型被删除,例如int只发生一次.
我真的不知道,如果这可以以某种方式完成.
#include <boost/variant.hpp>
#include <boost/any.hpp>
#include <iostream>
struct Person;
typedef boost::variant<int, double, boost::variant<std::string, int>, boost::variant<Person>> TNested;
typedef boost::variant<int, double, std::string, Person> TFlatten;
template<typename NestedVariant>
using flatten = //???
int main() {
flatten<TNested> x;
std::cout << typeid(x) == typeid(TFlatten) << std::endl;
}
Run Code Online (Sandbox Code Playgroud) c++ boost-variant boost-mpl template-meta-programming variadic-templates
我有一个类似于此处描述的问题:C++相互递归变体类型
我试图在C++中创建一个JSON表示.许多库已经提供了非常快的优秀 JSON表示和解析器,但我并没有重新发明这个轮子.我需要创建一个C++ JSON表示,支持在特定条件下的某些空间优化.简而言之,当且仅当JSON数组包含同质数据,而不是将每个元素存储为膨胀变体类型时,我需要本机类型的紧凑存储.我还需要支持异构数组和标准嵌套JSON对象.
以下是"如果希望是马,乞丐会骑"版本的代码,这是为了清楚地说明意图,但显然是因为在任何声明存在之前使用类型而被破坏.我想避免在类型中多次指定相同的信息(即Array,Object和Value不应该需要重复的类型规范).我还想避免任何不必要的高运行时间成本.
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/variant.hpp>
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>
class JSONDocument {
public:
using String = std::string;
using Integer = long;
using Float = double;
using Boolean = bool;
using Null = void *;
using Key = std::string;
using Path = std::string;
using Value = boost::variant<
Null,
String,
Integer,
Float,
Boolean,
Object,
Array
>;
using Object = std::unordered_map<Key,Value>;
using Array = boost::variant<
std::vector<Null>,
std::vector<String>,
std::vector<Integer>,
std::vector<Float>,
std::vector<Boolean>,
std::vector<Value> >;
private: …Run Code Online (Sandbox Code Playgroud) boost-variant ×10
c++ ×10
boost ×7
c++11 ×2
json ×2
boost-mpl ×1
boost-spirit ×1
c++14 ×1
composite ×1
gcc ×1
unique-ptr ×1