gpt4 book ai didi

c++ - 作为类模板参数的静态函数 - 导致可维护性问题

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:20 24 4
gpt4 key购买 nike

在学习了如何将静态函数(HashFunction)作为类(Collection<T,HashFunction>)模板参数传递之后,我对它上瘾了。

我在很多地方都用过它......现在我才意识到如果我想改变HashFunction的签名,我将不得不修改各个位置的代码。

例子

有一些类(BC)被设计用作自定义集合(Collection<T,HashFunction>)的元素:-

class B{
int bHash;
public: static int& getHash(B& b){return b.bHash;} //#1
//.... other complex thing about B ....
};

class C{
int cHash1;
public: static int& getHash1(C& c){return c.cHash1;} //#2
int cHash2;
public: static int& getHash2(C& c){return c.cHash2;} //#3
//.... other complex thing about C ....
};
//There are about 20 places, i.e. #1 to #20
//They have a thing in common : return an integer field

Collection<T,HashFunction> (未显示其代码)与 T 的哈希集类似.

这是用法:-

Collection<B,&B::getHash> collectB;
Collection<C,&C::getHash1> collectC1;
Collection<C,&C::getHash2> collectC2;
//There are about 30+ locations.

问题

散列函数的签名(#1#2#3 和内部 Collection)将来可能需要更改。

例如,签名可能从

int bHash;
static int& getHash(B& b){return b.bHash;}

HashStructure bHash; //"HashStructure" is a new class
static HashStructure& getHash(B& b,int notUsed){return b.bHash;}
//They tend to still have a thing in common : return a "HashStructure" field

//Here is the maximum possible difference :-
HashStructure bHash[3];
static HashStructure& getHash(B& b,int index){return b.bHash[index];}
//They are likely consistent for both B and C.

改变 Collection使用新签名并不难,但要更改 #1 的所有签名至 #20很乏味。

这表明存在可维护性问题。

问题

假设我可以将时间倒转到只有#1的时候至 #3 ,如何修改代码/设计(在示例中)以防止可维护性问题。

意见:

  • 我应该使用继承(AB 派生自新类),
    但它不适合。 (因为B可以有无限数量的哈希函数,而且哈希函数的名称很可能与A的不同。)

  • 一些特定的设计模式可能会有所帮助。 (?)

  • 可变参数模板和 SFINAE 可能会有所帮助。 (来自 Danh 的评论,谢谢!)

最佳答案

为了防止可维护性问题,我一开始就不会使用函数作为模板参数。我会选择 1 type == 1 hash function 设计,类似于 STL 为解决相同问题所做的工作。

无论出于何种原因必须将不同的散列函数粘贴到同一个类中,都可以使用继承或友元来解决。

这样,签名更改时只需更新调用站点。您还可以提供两个签名,直到每个调用站点都已更新,从而允许您逐步更新代码库。

例子:

#include <utility>

class C {
static int cHash1;
};
int C::cHash1 = 0;

struct C1 : public C {
static int hash(C &value);
static int hash(C &value,bool);
};

struct C2 : public C {
static int hash(C &value);
static int hash(C &value,bool);
};

template <class Value, class HashFunction>
struct Collection {
using key_type = decltype(HashFunction::hash(std::declval<HashFunction&>()));
};

template <class Value, class HashFunction>
struct CollectionUpdated {
using key_type = decltype(HashFunction::hash(std::declval<HashFunction&>(), std::declval<bool>()));
};

int main() {
Collection<int, C1> c1;
Collection<int, C2> c2;
CollectionUpdated<int, C1> c1_up;
CollectionUpdated<int, C2> c2_up;
return 0;
}

关于c++ - 作为类模板参数的静态函数 - 导致可维护性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41560531/

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