工厂返回提升::访客对象
Factory returning boost::visitor objects
我希望创建一个访客工厂,它返回以下任一类型的对象:
class Visitor1: public boost::static_visitor<int>
{
public:
int operator()(int& ) const
{
return 1;
}
int operator()(bool& ) const
{
return 1;
}
};
class Visitor2: public boost::static_visitor<int>
{
public:
int operator()(int& ) const
{
return 2;
}
int operator()(bool& ) const
{
return 2;
}
};
我假设我可以为工厂创建的对象返回 boost::static_visitor* 类型的指针,但这无法编译。我也不能引用该对象,如下所示:
Visitor1 v;
Type t;
boost::static_visitor<int>& vR = v;
boost::apply_visitor(vR, t);
我得到的错误是:
see reference to function template instantiation 'int boost::apply_visitor<boost::static_visitor<R>,Type>(Visitor &,Visitable &)' being compiled
1> with
1> [
1> R=int,
1> Visitor=boost::static_visitor<int>,
1> Visitable=Type
1> ]
1>c:boost_1_49_0boostvariantvariant.hpp(858): error C2064: term does not evaluate to a function taking 1 arguments
我应该如何实施我的工厂?
访问者使用重载,这意味着它们是静态组件。工厂总是 (?) 意味着运行时组件。首先,确定所有派生访问者是否共享同一组重载非常重要。如果是这样,您可以使用此方案:
#include <memory>
#include <boost/variant.hpp>
#include <boost/variant/static_visitor.hpp>
struct visitor_base : public boost::static_visitor<int>
{
virtual int operator()(int) = 0;
virtual int operator()(double) = 0;
virtual int operator()(const char*) = 0;
virtual ~visitor_base() {}
};
struct impl_1 : visitor_base {
virtual int operator()(int) { return 1; }
virtual int operator()(double) { return 1; }
virtual int operator()(const char*) { return 1; }
};
struct impl_2 : visitor_base {
virtual int operator()(int) { return 2; }
virtual int operator()(double) { return 2; }
virtual int operator()(const char*) { return 2; }
};
std::unique_ptr<visitor_base> visitor_factory(int i) {
if(i == 1) {
return std::unique_ptr<visitor_base>(new impl_1);
} else {
return std::unique_ptr<visitor_base>(new impl_2);
}
}
int main()
{
auto vis = visitor_factory(1);
boost::variant<int, double, const char*> v = 3;
std::cout << boost::apply_visitor(*vis, v) << std::endl;
auto vis2 = visitor_factory(2);
std::cout << boost::apply_visitor(*vis2, v) << std::endl;
return 0;
}
如果您的派生访问者仅用于应用于变体中可能类型的子集,则不能使用纯虚函数,并且需要一些报告失败的机制来处理基中的值(例如异常)。
当然,示例代码中使用的少数 C++11 功能很容易替换。
#include <memory>
#include <string>
#include <boost/variant.hpp>
#include <boost/variant/static_visitor.hpp>
struct visitor_base : public boost::static_visitor<int>
{
// the catch all
template <typename T>
int operator()(const T& t) {
return 0;
}
virtual int operator()(int) {}
virtual int operator()(double) {}
virtual int operator()(const char*) {}
virtual ~visitor_base() {}
};
struct impl_1 : visitor_base {
virtual int operator()(int) { return 1; }
virtual int operator()(double) { return 1; }
virtual int operator()(const char*) { return 1; }
};
struct impl_2 : visitor_base {
virtual int operator()(int) { return 2; }
virtual int operator()(double) { return 2; }
virtual int operator()(const char*) { return 2; }
};
std::unique_ptr<visitor_base> visitor_factory(int i) {
if(i == 1) {
return std::unique_ptr<visitor_base>(new impl_1);
} else {
return std::unique_ptr<visitor_base>(new impl_2);
}
}
int main()
{
auto vis = visitor_factory(1);
boost::variant<int, double, const char*> v = 3;
std::cout << boost::apply_visitor(*vis, v) << std::endl;
auto vis2 = visitor_factory(2);
std::cout << boost::apply_visitor(*vis2, v) << std::endl;
// a variant with more than impl_1 and impl_2 can catch
boost::variant<int, double, const char*, std::string> vv = std::string{"asdf"};
std::cout << boost::apply_visitor(*vis2, vv) << std::endl;
// no use one that we handle
vv = 3;
std::cout << boost::apply_visitor(*vis2, vv) << std::endl;
return 0;
}
相关文章:
- 在访客模式中组合访客
- 隐藏重载虚拟功能的模板化访客:SFINAE 在使用?
- C++提升::获取和访客
- 如何消除访客模式冗余?
- 虚拟模板函数:使用参数实现访客模式
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- 访客设计模式和多层类层次结构
- VirtualBox访客添加汇编
- 具有不同返回类型的变体访客
- 基类中的访客模式
- 提升::访客操作员过载的变体"Error: no match for call to [...]"
- 为什么在 BGL 中的访客中无法更改边缘属性?
- 非周期访客C++
- C++ 访客模式与子类节点上的访客失去"is a"关系
- 访客模式适用于shared_ptr或原始指针?
- 提升变体和访客
- Lambdas的多态性访客
- 工厂返回提升::访客对象
- 提升的访客模式::任何
- 从服务应用程序访问访客帐户系统注册表