Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将`boost::static_visitor`实例传递给函数_C++_Templates_Boost_Visitor_Boost Variant - Fatal编程技术网

C++ 如何将`boost::static_visitor`实例传递给函数

C++ 如何将`boost::static_visitor`实例传递给函数,c++,templates,boost,visitor,boost-variant,C++,Templates,Boost,Visitor,Boost Variant,我在项目中经常使用boost::variant。我的同事们现在想出了一个主意,通过传递特定的boost::static\u visitor实例来定制访问类型。她有如下代码: #include <boost/variant.hpp> #include <iostream> typedef boost::variant<int, std::string> TVar; struct Visitor1 : public boost::static_visitor&

我在项目中经常使用
boost::variant
。我的同事们现在想出了一个主意,通过传递特定的
boost::static\u visitor
实例来定制访问类型。她有如下代码:

#include <boost/variant.hpp>
#include <iostream>

typedef boost::variant<int, std::string> TVar;

struct Visitor1 : public boost::static_visitor<int> {
    template<typename T> 
    result_type operator()(const T&) {
        return 42;
    }
};

struct Visitor2 : public boost::static_visitor<int> {
    template<typename T>
    result_type operator()(const T&) {
        return 21;
    }
};

 int adder(const boost::static_visitor<int>& visitor, const TVar& visitable) {
     return visitable.apply_visitor(visitor) + 1;
 }

int main(int argc, char **args) {
    Visitor1 v1;
    Visitor2 v2;
    TVar x;

    std::cout << adder(v1, x) << std::endl;
    std::cout << adder(v2, x) << std::endl;
}
#包括
#包括
typedef boost::变型TVar;
结构访问者1:public boost::static\u访问者{
模板
结果类型运算符()(常量T&){
返回42;
}
};
结构访问者2:public boost::static\u访问者{
模板
结果类型运算符()(常量T&){
返回21;
}
};
整数加法器(常量boost::static_visitor&visitor、常量TVar&visitable){
返回访问表。应用_访问者(访问者)+1;
}
int main(int argc,char**args){
访问者1 v1;
访问者2 v2;
tvarx;

std::cout对于
apply\u visitor
有一个重载,它只接受访问者。这将返回一个部分应用的函数对象,适合您的需要,我想:

此重载返回一个

就个人而言,我喜欢向访问者对象添加重载,如下所示:

struct MyVisitor {
    typedef void result_type;

    template <typename... Ts>
    result_type operator()(boost::variant<Ts...> const& v) const {
         return boost::apply_visitor(*this, v);
    }
    // optionally repeat for non-const `v`

    // normal variant handling overloads
};
struct MyVisitor{
typedef void result_type;
模板
结果类型运算符()(boost::variant const&v)const{
返回boost::apply_visitor(*this,v);
}
//可选地对非常量'v重复此操作`
//正常变量处理重载
};

这样,您就可以简单地将访问者对象用作函数对象。

static\u visitor
不是多态基类,不能这样对待。它的名字很简单:它是一个static(静态类型)访问者。需要将访问者的静态类型作为要调用的类型。请注意,这是不可避免的,因为成员函数模板不能是虚拟的。在您的情况下,这意味着
adder
必须成为函数模板,由访问者类型模板化:

template <class Visitor>
int adder(const Visitor& visitor, const TVar& visitable) {
  return visitable.apply_visitor(visitor) + 1;
}

从技术上讲,访问者本身已经是一个合适的可调用对象,因此即使没有显式使用
apply\u visitor
,它也应该可以工作:

int main(int argc, char **args) {
    Visitor1 v1;
    Visitor2 v2;
    TVar x;

    std::cout << adder(v1, x) << std::endl;
    std::cout << adder(v2, x) << std::endl;
}
intmain(intargc,char**args){
访问者1 v1;
访问者2 v2;
tvarx;

std::cout首先,您应该将访问者的
操作符()重载标记为
const

struct Visitor1 : public boost::static_visitor<int> {
    template<typename T> 
    result_type operator()(const T&) const {
        return 42;
    }
};

struct Visitor2 : public boost::static_visitor<int> {
    template<typename T>
    result_type operator()(const T&) const {
        return 21;
    }
};

Ouch!太明显了。谢谢你的帮助。我真的不习惯这个模板。非常有趣。我甚至没有意识到这个调用。但我仍然不确定如何使用它。假设我有
auto y=boost::apply\u visitor(v1)
。我如何将
y
传递给我的
加法器
函数?传递它就像传递可调用对象的任何位置一样(使用模板类型参数推断参数类型,或使用
std::function
或类似方法清除该类型)非常感谢。我认为Angew已经向我展示了如何做到这一点。:-)事实上。这也是他的方法的一部分,似乎也是一个非常酷的解决方案。不幸的是,它没有编译。我的visual studio编译器有问题吗?它应该支持C++11。它说从
boost::apply\u visitor\u t
转换为
const std::函数&
不可能。我将传递的变量
visitorApplier
作为常量引用。刚刚发现,您可以用
adder(v1,x)
替换
adder(boost::apply_visitor(v1,x)
。这样您甚至可以缩短解决方案。
struct Visitor1 : public boost::static_visitor<int> {
    template<typename T> 
    result_type operator()(const T&) const {
        return 42;
    }
};

struct Visitor2 : public boost::static_visitor<int> {
    template<typename T>
    result_type operator()(const T&) const {
        return 21;
    }
};
template <typename T>
int adder(const T& visitor, const TVar& visitable) {
    return visitable.apply_visitor(visitor) + 1;
}