gpt4 book ai didi

c++ - 封装多种类型的 Datastructure 并公开它们的所有功能

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:09:36 26 4
gpt4 key购买 nike

我有 6 种 datastructure<T> .

它们都包含覆盖 10-20 个常用函数(紫色),例如addFirst() .

然而,一些数据结构有自己的0-5个独特的功能(粉红色)。
例如,只有 MyArray<T>具有功能addManual(T,int) .
在极少数情况下,一些不同类型的数据结构支持一些相同的特殊功能。

enter image description here
(实际情况表要复杂 10 倍左右。)

这是一个简短的片段:-

class Vector3D{};
template<class T>class MyArray{
public: void addFirst(T t){/* some code */}
/* other add / remove / query function */
public: void addManual(T t,int internalIndex){/* some code */}
};
template<class T>class MyGrid3D{
public: void addFirst(T t){/*some code */}
/* other add / remove / query function */
public: void addSpecial(T t,Vector3D gridAddress){/* some code*/}
};

到目前为止效果很好。
现在,我想通过提供接口(interface) Adapter<MyX,T,I> 来简化它的使用.
我图书馆的用户可以识别内部存储类型T和界面I分别地。

只要函数(紫色/粉色)的参数类型为 I , 我会将其转换为 T并在内部对其进行操作,就好像它具有类型 T .

这是我的原型(prototype):-

template<template<class> class MyX,class T,class I>class Adapter{
private: T convert(I i){/* some logic */ return T();}
MyX<T> database;
public: void addFirst(I i){
database.addFirst(convert(i));
}
};
int main() {
Adapter<MyArray,int,std::string> adapter;
adapter.addFirst(std::string("5.0f"));
std::cout<<"compiled OK";
return 0;
}

效果很好( coliru demo ),但不包括特殊功能(紫色),例如addManual()addSpecial() .

问题

什么是设计模式/C++ 魔法 Adapter支持那些功能?

这是我的三个糟糕的解决方案:-

  1. 为每种类型的数据结构创建许多适配器类,例如AdapterMyArray<T,I>AdapterMyGrid3D<T,I> .

  2. 通过继承改进第一个解决方案,例如AdapterMyArray<T,I>AdapterMyGrid3D<T,I>源自 AdapterBase<T,I> .

  3. 检查 MyX 的类型并使用 std::enable_if启用这些特殊功能的实例化。

我觉得我所有的解决方案都过于手动,这会导致一些可维护性问题。

编辑: Yakk 的解决方案很好,但我仍然怀疑是否有更好的解决方案。

最佳答案

CRTP。

Adapter_addFirst Adapter_addManual等等 CRTP 助手。他们使用 CRTP 访问 database<T>并实现他们的一个(或一组)功能。

Adapter查询 databasedatabase<T>通过 traits 类助手来确定哪个 CRTP Adapter_*它应该(公开地)继承自。

template<class D, class I>
class Adapter_addFirst {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D*>(this); }
public:
void addFirst(I i){
self()->database.addFirst(self()->convert(i));
}
};
template<std::size_t I>
struct empty_t {};
template<template<class> class MyX,class T,class I>
class Adapter:
public std::conditional_t<true, Adapter_addFirst<Adapter<MyX, T, I>, I>, empty_t<0>>
{
friend struct Adapter_addFirst<Adapter<MyX, T, I>, I>;
private:
T convert(I i){/* some logic */ return T();}
MyX<T> database;
};

哪里true替换为“我应该添加 First”的测试。

对每个方法重复。

Dispatch 是静态的,方法只在应有的情况下存在,一切都符合标准。

您可以通过类型上的标签、类型特征或什至是调用 std::declval<MyX<T>&>().addManual( std::declval<T const&>() ) 的 SFINAE 测试来测试“我应该添加手册”吗? .对于 SFINAE 案例,请参阅 can_apply或等效的。

关于c++ - 封装多种类型的 Datastructure<T> 并公开它们的所有功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43914244/

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