gpt4 book ai didi

c++ - 没有虚拟方法的设计模式 "Container Visitor"?

转载 作者:行者123 更新时间:2023-11-30 02:11:07 40 4
gpt4 key购买 nike

我正在开发一个应用程序的设计,我想我可能会应用某种 Visitor design pattern ,但事实证明这并不是我要找的。也许有人可以指出我在这种情况下需要的变体?

我的大部分代码都有一个模板参数“ContainerType”,比如

template <class ContainerType>
class MyClass
{
public:
void doSomething(ContainerType& container) { ... }
};

“容器”目前数量很少,但数量在不断增加,它们通常共享许多数据字段。

template<class ContainedType>
struct ContainerBase
{
ContainedType data;
};

struct Container1: ContainerBase<A>, ContainerBase<B>
{};
struct Container2: ContainerBase<A>, ContainerBase<C>
{};

Container1 和 Container2 现在用作 MyClass(和其他类)的模板参数,其中 A、B、C 是一些已定义的类。 (我有一些方法可以执行类似 get<A>(container) 的操作来访问包含的数据。此设计提供了编译时安全性,即 MyClass 可以与包含所需类型的所有容器类型一起使用。)

现在我想添加“如果 Container 包含特定类型(例如 A),则执行某些操作,否则什么都不执行”的功能。

这可以用看起来像访问者的东西来完成(但请注意,没有使用虚拟方法)。它甚至允许“如果容器包含 A 则执行此操作,如果它包含 D 则执行其他操作,否则什么都不做”。这可以用

template <class ContainerType>
class MyClass
{
public:
void doSomething(ContainerType& container)
{
container.accept(*this);
}

void visit(B& b){...}
void visit(D& d){...}

template<typename T>
void visit(T& t){}
};


struct Container1: ContainerBase<A>, ContainerBase<B>
{
template<class T>
void accept(T& t)
{
t.visit(ContainerBase<A>::data);
t.visit(ContainerBase<B>::data);
}
};

这是我想要的,但我正在寻找一种更好的方法来实现它,因为这里显示的实现需要为每个 ContainerType 实现接受。如果有人派生自 Container1ContainerBase<D>但是忘记扩展接受方法,事情就会变得糟糕。更糟糕的是,我将需要 accept 的 const 和非 const 版本,并且一些容器包含超过 5 种类型,因此看起来也不会很漂亮。

所有的容器类都是从ContainerBase<T>继承而来的多次,所以我想知道我是否可以使用这个结构来实现ContainerBase类中的accept(和accept(..)const)?我已经看过 Lokis typelists,但我不知道如何在这里使用它们。你有什么想法吗?

或者没有类似访问者的结构是否可以做这件事?

非常感谢!

编辑:我知道我可以使用 RTTI,但我想尽可能避免运行时检查和虚拟方法。

最佳答案

如果你能改变容器类的定义方式,看起来用 Boost.Fusion 可以很容易地实现

例如

#include <iostream>

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>

struct A {};
struct B {};
struct C {};

namespace fusion = boost::fusion;

struct Container1 : fusion::vector< A, B > {};

struct Container2 : fusion::vector< A, C > {};

struct doSomethingWithData {
void operator()( B &b ) const
{
std::cout << "do something with B" << std::endl;
}

void operator()( C &c ) const
{
std::cout << "do something with C" << std::endl;
}

template < typename T >
void operator()( T &t ) const
{
std::cout << "Neither B nor C" << std::endl;
}
};

template < typename ContainerType >
void doSomething( ContainerType &container )
{
fusion::for_each( container, doSomethingWithData() );
}

int main()
{
Container1 c1;
doSomething( c1 );
std::cout << "----------------------" << std::endl;
Container2 c2;
doSomething( c2 );
}

关于c++ - 没有虚拟方法的设计模式 "Container Visitor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3896484/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com