提升二进制static_visitor和apply_visitor
Boost binary static_visitor and apply_visitor
我有以下代码:
typedef boost::variant<LandSearchParameter, WaterSearchParameter> SearchParameter;
enum Visibility{
CLEAR,
CLOUDY,
FOG,
SMOKE
};
class DetectionGenerator : public boost::static_visitor<double>{
public:
DetectionGenerator(const EnvironmentalFactors& factors);
double operator()(const LandSearchParameter& land, Visibility vis) const;
double operator()(const WaterSearchParameter& water, Visibility vis) const;
private:
const EnvironmentalFactors mFactors;
};
但是如果我尝试以以下方式boost::apply_visitor
使用它:
SearchParameter param = globeCover.generateSearch(lat, lon, altitude);
Visibility vis = weather.generateVisibility(lat, lon, altitude, bearing);
DetectionGenerator detectGen(envFactors);
double prob = boost::apply_visitor(detectGen, param, vis);
并从 GCC 获取以下内容:
错误:调用
‘apply_visitor(const SearchRescue::DetectionGenerator&, const boost::variant<boost::tuples::tuple<double, double, double, double, double, bool, bool, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, boost::tuples::tuple<std::size_t, std::size_t, double, double, double, bool, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&, SearchRescue::Visibility)
没有匹配函数
如果我尝试将Visibility
枚举包装在boost::variant
中,我只会收到相同的错误,而不是Visibility
它读取上面的所有垃圾以及我为变体选择的任何名称。 我已经阅读了有关二进制访问提升的文档,但我不知所措。 请注意,所有这些内容都位于同一个命名空间中。
更新:
问题是我的尝试。 上面没有显示的是我将访问者作为const
变量。 一旦我把const
从图片中取出,它就编译了。 谢谢大家试图帮助我。 希望我能给更多的赞成票。
@Boaz Yaniv的答案是100%正确的。boost::apply_visitor<>
文档直接指出:
接受两个操作数的重载在给定变体操作数的内容上调用给定访问者的二进制函数调用运算符。
Yaniv 建议的补救措施——在访问者的构造函数中获取Visibility
对象——也是正确的解决方法。你表示这种方法对你不起作用;我保证问题出在您的尝试中,而不是在方法上。;-] 这是编译的代码:
#include <boost/variant.hpp>
struct LandSearchParameter { };
struct WaterSearchParameter { };
struct EnvironmentalFactors { };
typedef boost::variant<
LandSearchParameter,
WaterSearchParameter
> SearchParameter;
enum Visibility
{
CLEAR,
CLOUDY,
FOG,
SMOKE
};
struct DetectionGenerator : boost::static_visitor<double>
{
DetectionGenerator(EnvironmentalFactors const& factors, Visibility vis)
: mFactors(factors),
mVis(vis)
{ }
double operator ()(LandSearchParameter const&) const { return 0.; }
double operator ()(WaterSearchParameter const&) const { return 0.; }
private:
EnvironmentalFactors mFactors;
Visibility mVis;
};
int main()
{
SearchParameter param = LandSearchParameter();
EnvironmentalFactors const envFactors;
DetectionGenerator const detectGen(envFactors, CLOUDY);
double const prob = boost::apply_visitor(detectGen, param);
}
如果此方法仍然不适合您,那么您需要编辑您的问题并使用实际的当前代码对其进行更新。
附言你把Visibility
做成单一类型boost::variant<>
的方法也应该行得通,尽管这对我来说似乎很愚蠢。作为参考,这将编译:
#include <boost/variant.hpp>
struct LandSearchParameter { };
struct WaterSearchParameter { };
struct EnvironmentalFactors { };
typedef boost::variant<
LandSearchParameter,
WaterSearchParameter
> SearchParameter;
enum VisibilityT
{
CLEAR,
CLOUDY,
FOG,
SMOKE
};
typedef boost::variant<VisibilityT> Visibility;
struct DetectionGenerator : boost::static_visitor<double>
{
explicit DetectionGenerator(EnvironmentalFactors const& factors)
: mFactors(factors)
{ }
double operator ()(LandSearchParameter const&, VisibilityT const) const
{ return 0.; }
double operator ()(WaterSearchParameter const&, VisibilityT const) const
{ return 0.; }
private:
EnvironmentalFactors mFactors;
};
int main()
{
SearchParameter param = LandSearchParameter();
EnvironmentalFactors const envFactors;
DetectionGenerator const detectGen(envFactors);
Visibility vis = CLOUDY;
double const prob = boost::apply_visitor(detectGen, param, vis);
}
boost::apply_visitor 只接受一个接受单个参数的访问者,所以它不会接受你的访问者。您可以使用一些绑定来修复它,但我认为更好的解决方案是在 DetectionGenerator 类构造函数中添加可见性参数:
class DetectionGenerator : public boost::static_visitor<double>{
public:
DetectionGenerator(const EnvironmentalFactors& factors, Visibility vis);
double operator()(const LandSearchParameter& land) const;
double operator()(const WaterSearchParameter& water) const;
private:
const EnvironmentalFactors mFactors;
const Visibility mVis;
};
SearchParameter param = globeCover.generateSearch(lat, lon, altitude);
Visibility vis = weather.generateVisibility(lat, lon, altitude, bearing);
DetectionGenerator detectGen(envFactors, vis);
double prob = boost::apply_visitor(detectGen, param);
至于二元访问,我认为这不是你要找的。它允许apply_visitor接受两个参数,但两个参数都必须是变体。
- 如何通过 std::apply 调用具有定义的第一个参数的可变参数模板函数?
- 为什么我们需要在 Visitor 模式中 accept(),为什么我们不能直接调用 visitor.visit()?
- Antlr4 c++ visitor API
- 如果结果存储在变量中forward_as_tuple然后在 std::apply 中使用之前丢失右值引用
- std::apply是否为评估顺序提供保证
- 用std :: apply迭代元组元素
- 为什么 std::apply 使用泛型函数失败
- 为什么 std::apply 可以调用 lambda 而不是等效的模板函数?
- 哪种算法需要"visitor"(提升库中的术语)?
- 使用模板实现"visitor pattern"
- 修改后的std::invoke/std::apply,将可调用项作为void*-possible
- boost::mpl::apply 仅适用于类型化模板参数
- 关于"Node,File,Directory,Link"和"Visitor"
- 如何检查类型是否为mpl::apply-able
- std::apply可能未正确实现
- CD对话框中的Apply按钮
- 在哪里存储Visitor模式中访问的每个元素的计算结果
- 在c++中,在typelist上键入visitor
- std::apply和常量表达式
- 使用std::apply应用可变函数