boost :: variant。boost :: visitor重载功能

卡比克

我对重载函数的变体值有疑问。我想根据变量中存储的内容使用int或字符串调用重载函数。这就是我想要的方式,但是我不能:

class X
{
    void foo(int i, int z) { /*use int i and z*/; }
    void foo(const std::string& s, int z) { /*use string s and z*/; }


    struct MyVisitor : public boost::static_visitor<int>  
    // !!! Here is the problem.
    // I can't return int or std::string,
    // so it's impossible to use template operator()
    {
        template<typename Data>
        const Data operator()(const Data data) const { return data; }
    };

public:

    /*somehow m_queue pushed ...*/

    void func_uses_variant(int z)
    {
        boost::variant<int, std::string> v = m_queue.pop();
        foo(boost::apply_visitor(MyVisitor(), v), z);
    }
private:
    SomeQueue m_queue;
}

是否可以使用visitor编写它,还是应该执行以下操作:

    void func_uses_variant(int z)
    {
        boost::variant<int, std::string> v = m_queue.pop();

        if (int* foo_arg = boost::get<int>(&v))
        {
            foo(*foo_arg, z);
        }
        else if (std::string* foo_arg = boost::get<std::string>(&v))
        {
            foo(*foo_arg, z);
        }
    }

我试图对MyVisitor使用variadics,但由于boost :: static_visitor接口而失败。也许有解决方案。

int z in函数只是为了表明foo()参数中不仅存在boost :: variant。

彼德

访问者的全部目的是处理该变体可能包含的每种不同类型,其形式不涉及get(),允许泛型,并且可以很容易地告诉您已经处理了所有选项。如果您可以在一个通用函数中全部处理它们,那么您可以在访问者中编写一个模板函数。如果不是,请更具体:

struct foo_visitor : public boost::static_visitor<std::string>  
{
    std::string operator()(int & i) const { return "this is int"; }
    std::string operator()(std::string &s) const { return "this is string"; }
};

这将从变体中的每种可能的类型返回一个公共值。或者,您也可以使用访问者包装外部函数。回到模板功能:

struct foo_visitor : public boost::static_visitor<void>  
{
    template<typename Data>
    void operator()(const Data &d) const { foo(d); }
};

EDIT [似乎是由库以形式提供的visitor_ptr,用于单参数函数。我认为boost::visitor_ptr(foo)可能完全相同。]

对于额外的参数,您可以向访问者添加一个构造函数,并存储一个额外的数据成员,该成员将被传递到包装函数中:

struct foo_visitor : public boost::static_visitor<void>  
{
    int z;
    foo_visitor(int z_param) : z(z_param) {};

    template<typename Data>
    void operator()(const Data &d) const { foo(d, z); }
};

{
    boost::variant<int, std::string> v;
    v = 5;
    int z = 0;
    boost::apply_visitor(foo_visitor(z), v);
}

从@Kabik编辑:

有一种方法可以通过将模式匹配与boost make_overloaded_function()和lambda一起使用来实现。

链接到实验匹配功能-http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0050r0.pdf

boost::variant<int, std::string> v;
v = 5;
int z = 0;
boost::apply_visitor(boost::bind<void>(boost::make_overloaded_function(
   [&](const int i) { foo(i, z); },
   [&](const std::string& str) { foo(str, z); }) _1
), v);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用boost :: visitor和unique_ptr的boost :: variant

std::variant 是否提供类似于 boost::variant<>::types 的功能?

C ++运算符[]通过模板访问boost :: variant的重载

使用boost :: variant C ++隐式运算符重载

增量boost :: variant值

Boost-variant的向量

从boost :: variant检索对象

boost :: variant将static_visitor应用于某些类型

boost :: make_recursive_variant没有名为'apply_visitor'的成员

Boost Karma:使用boost :: optional <boost :: variant <... >>编写规则

从istream读取boost :: variant类型

Boost :: variant的多态设置器

嵌套Boost :: variant的分段错误

访问者运算符重载时的Boost :: Variant“错误:与[...]的调用不匹配”

Boost Variant是否提供与std的hold_alternative类似的功能?

Boost.Spirit语法的属性:boost :: variant的std:vector错误

通过boost :: mpl获得boost :: variant的类型索引

solr boost功能的目的

使用boost :: variant获得理智的比较器

boost :: variant和多态性

从boost :: variant和模板化AST继承

布尔和字符串的boost :: variant

std :: variant和boost :: variant之间有什么区别?

boost :: static_visitor无法使用多种可能的类型来专门化功能模板

是否可以将boost :: any或boost :: variant与boost :: pool一起使用?

从给定的嵌套boost-variant类型创建新的boost-variant类型

将Boost Spirit解析器从boost :: variant过渡到std :: variant 2

模板功能的`boost :: hana`自省

解释Apache SOLR Boost功能