我在我的代码中使用了很多变量,我需要在某些地方与内容进行比较,以测试变量的内容的价值.
例如:
if(equals<int>(aVariant, 0)){
//Something
} else {
//Something else
}
Run Code Online (Sandbox Code Playgroud)
使用这个简单的模板函数,我为此目的写了:
template<typename V, typename T>
inline bool equals(V& variant, T value){
return boost::get<T>(&variant) && boost::get<T>(variant) == value;
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但代码开始难以阅读.我更喜欢使用这样的比较运算符:
if(aVariant == 0){
//Something
} else {
//Something else
}
Run Code Online (Sandbox Code Playgroud)
但我无法提供有效的运营商实施.问题是,==运算符已在变量中实现,在编译时失败...
有人知道一种方法来实现它吗?或者一种禁用此限制的方法?即使我必须为变体中包含的每种可能类型实现一个版本,这也不是问题.
谢谢
我试图用变体表示c ++中的PDF对象类型.PDF对象是以下之一:
BooleanIntegerRealStringNameStreamArray<Object>Map<Object, Object>如您所见,Object类型是相互递归的,因为Array类型需要声明Map类型,这需要声明Array类型.我怎么能在c ++中代表这种类型呢?如果变体不是最好的方式,那是什么?
以下是我到目前为止所尝试但由于std::unordered_map(我认为)http://coliru.stacked-crooked.com/a/699082582e73376e的要求而无法编译
鉴于:
boost::variant<T1,T2,T3,...,TN>
Run Code Online (Sandbox Code Playgroud)
在编译时计算以下内容:
max(sizeof(T1), sizeof(T2), sizeof(T3),... ,sizeof(TN))
Run Code Online (Sandbox Code Playgroud)
我不知道如何处理这个,但这个答案揭示了我如何开始.使用两个类型的答案中的代码,T1并且T2,我可以在源文件中使用以下内容来获取更大对象的大小:
size_t largestSize = sizeof(largest<T1, T2>::type);
Run Code Online (Sandbox Code Playgroud)
这正是我想要做的,但我需要largest模板来处理两个以上的类 - 具体来说,它需要检查存储在boost::variant对象中的所有类型.
我知道boost::variant有一个typestypedef,它定义了变体中某种类型的列表.问题是,当我试图绕过实现中的所有boost::mpl内容时,我完全迷失了.我不直观地了解什么boost::variant::types 是的,我如何能够将它传递到我自己的模板做了它.
在我看来,这是最终实现的样子:
typedef boost::variant<T1, T2, T3, T4> MyVariant;
size_t largestSize = sizeof(largest<MyVariant::types>::type);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不知道如何实现这个版本largest.
我不确定这是否是一种合理的方法,所以我愿意接受任何其他方法来实现这一点(可能boost::static_visitor在编译时应用于所有类型?).
假设我有一个Shape基类Circle,Line以及Point派生类。我有两个功能。
std::variant<Circle, Line, Point> process(const Shape &s);
Shape process(const Shape& s);
Run Code Online (Sandbox Code Playgroud)
我可以传入我的任何派生类并在第二个函数中返回一个 Shape 对象,变体只是一个联合,可以在任何给定时间保存我的任何派生类变量。
现在std::variant我还可以使用一个visitor我可以根据我的变体当前持有的类型处理一些函数的地方(我可以创建一个函数对象并传递它std::transform并将其应用于我的每个对象)。但是,我可以virtual在我的基类中创建该函数并让每个派生类实现它。
那么,variant仅仅是一种方便吗?
我想创建一个函数,它可以使用不同类型的迭代器来存储相同类型的对象:
第一个是std::map包含shared_ptr<Foo>(typedef-ed as FooMap),另一个是std::list包含shared_ptr<Foo>(FooList)的.
我非常喜欢MSalters为类似问题提出的解决方案并试图实现boost::variant迭代器,该函数将作为参数从第一个迭代到第二个迭代.
我的函数看起来像这样(简化了很多):
set<Foo> CMyClass::GetUniqueFoos(FooIterator itBegin, FooIterator itEnd)
{
set<Foo> uniques;
for(/**/;
apply_visitor(do_compare(), itBegin, itEnd); // equals "itBegin != itEnd"
apply_visitor(do_increment(), itBegin)) // equals "++itBegin"
{
// Exact mechanism for determining if unique is omitted for clarity
uniques.insert( do_dereference< shared_ptr<Foo> >(), itBegin) );
}
return uniques;
}
Run Code Online (Sandbox Code Playgroud)
FooIterator和访问者定义如下:
typedef
boost::variant<
FooMap::const_iterator,
FooList::const_iterator>
FooIterator;
struct do_compare : boost::static_visitor<bool>
{
bool operator() (
const …Run Code Online (Sandbox Code Playgroud) 如何比较boost :: variant以使其成为std :: map的关键?似乎没有为boost :: variant定义operator <()
昨天我问了这个问题并且"juanchopanza"回答了我的问题,但不幸的是我无法抓住其中一个有界类型.由于使用"访客"更加强大,我也想知道有人可以使用"访客"给我一个解决方案吗?
我正在寻找过滤boost变体矢量的最佳方法,该变量已定义如下:
boost::variant<T1*, T2, T3> Var;
std::vector<Var> Vec;
Run Code Online (Sandbox Code Playgroud)
当我调用这个向量时,什么是仅过滤T2有界类型并插入新向量的最佳方法?或者换句话说,我想要这样的东西
std::vector<T2> T2Vec =...(如何使用apply_visitor从Vec中过滤它)...
再次感谢!
编辑:@ ForEveR的闷闷不乐:
template<typename T>
struct T_visitor : public boost::static_visitor<>
{
T_visitor(std::vector<T>& v) : vec(v) {}
template<typename U>
void operator () (const U&) {}
void operator () (const T& value)
{
vec.push_back(value);
}
private:
std::vector<T>& vec;
};
Run Code Online (Sandbox Code Playgroud)
和:
std::vector<T1> t1vec;
T_visitor<T1> vis(t1vec);
std::for_each(vec.begin(), vec.end(), boost::apply_visitor(vis));
Run Code Online (Sandbox Code Playgroud)
你能告诉我这里有什么问题吗?
这是定义:
struct nmap;
struct nmap: map<string, boost::variant<string, nmap*>>{};
下面的最后一行不起作用:
nmap my_map;
my_map["a"] = "b";
my_map["c"] = new nmap;
my_map["c"]["d"] = "e";
我需要添加什么才能使其正常工作?
使用=不起作用.
我有这样的代码,但它有点"难".
#include <iostream>
#include <cassert>
#include <variant>
#include <string>
using namespace std;
namespace detail {
template<typename... L, typename... R>
void VariantAssignRec(variant<L...>* lhs, const variant<R...>&rhs, size_t rhs_idx, std::integral_constant<int, -1>) {
}
template<typename... L, typename... R, int get_idx>
void VariantAssignRec(variant<L...>* lhs, const variant<R...>&rhs, size_t rhs_idx, std::integral_constant<int, get_idx> = {}) {
assert(rhs_idx < std::variant_size_v< variant<R...>>);
if (get_idx == rhs_idx) {
cout << "assigning from idx " << get_idx << endl;
*lhs = std::get<get_idx>(rhs);
return;
}
else {
std::integral_constant<int, get_idx - …Run Code Online (Sandbox Code Playgroud) Boost 似乎有两种变体类模板的实现:
Boost 两个包含同一概念的两个版本的情况很少见(尽管并非闻所未闻)。为什么变体会发生这种情况?这些变体有何不同?