如何处理算法中具有不同名称成员函数的类?

How to handle classes with differently named member functions in algorithms?

本文关键字:成员 函数 何处理 处理 算法      更新时间:2023-10-16

我在C++中实现了算法。该算法可以处理具有某些共同属性的不同事物(对象(。该算法需要调用这些对象的某些成员函数。因此,当然,它需要函数名称才能执行此操作。现在,问题是,算法可能处理的事情可能完全不同。例如,请考虑以下说明性代码片段:

struct Zoo {
using NumAnimals = unsigned short;
Animal GetAnimal();
NumAnimals GetNumAnimals();
};
struct Library {
using NumBooks = size_t;
Book GetBook();
NumBooks GetNumBooks();
};
template<typename T>
void f(T t) {
do_something(t.Get???(), t.GetNum???()); // Get what?
}

放什么而不是问号?

我认为用GetThing((,GetItem((,GetObj((或类似的东西替换GetAnimal((和GetBook((是非常不方便的,然后让f调用该函数。GetNumAnimals(( 和 GetNumBooks(( 也是如此。但是如何在两个类的实例上调用算法 f?我们能在这里构建某种"名称翻译"(别名(而不会使动物园和图书馆混乱吗?

我想到的一个潜在解决方案是分别从 Zoo 和 Library 派生一个类,该类"代理"f 中的调用, 例如,对于动物园:

struct ZooProxy : public Zoo {
using Item = Animal;
using NumItems = NumAnimals;
Item GetItem() { return GetAnimal(); }
NumItems GetNumItems() { return GetNumAnimals(); }
};

然后将 f 中的???分别替换为 项目 和 项目。

还有其他(更好的(选择吗?

仅仅为了f而更改类ZooLibrary是没有意义的。

最好创建重载函数以f。您可以在这些函数中添加特定于f的代码,而不会影响类本身。

template<typename T>
void f(T t) {
do_something(geItemForF(t), getNumForF(t));
}
Animal const& geItemForF(Zoo const& zoo) { ... }
int getNumForF(Zoo const& zoo) { ... }
Book const& geItemForF(Libraryconst& library) { ... }
int getNumForF(Libraryconst& library) { ... }

另一种方式。

template<typename T, typename GetItem, typename GetItemCount>
struct Algorithm {
Algorithm(GetItem&& t, GetItemCount&& f):
getItem_m(t),
getItemCount_m(f) {}
bool operator() (T& t) {
std::cout << "Executing getItem_m: " << getItem_m(t) << std::endl;
std::cout << "Executing getItemCount_m: " << getItemCount_m(t) << std::endl;
}

GetItem getItem_m;
GetItemCount getItemCount_m;
};

int main () {
auto getAnimal = std::bind(&Zoo::GetAnimal, std::placeholders::_1);
auto getAnimalCount = std::bind(&Zoo::GetNumAnimals, std::placeholders::_1);
using AnimalAlgorithm = Algorithm<Zoo, decltype(getAnimal), decltype(getAnimalCount)>;
auto getBook = std::bind(&Library::GetBook, std::placeholders::_1);
auto GetBookCount = std::bind(&Library::GetNumbooks, std::placeholders::_1);
using LibraryAlgorithm = Algorithm<Library, decltype(getBook), decltype(GetBookCount)>;

AnimalAlgorithm aa(std::move(getAnimal), std::move(getAnimalCount));
LibraryAlgorithm la(std::move(getBook), std::move(GetBookCount));
Zoo z();
Zoo z1();
Library l();
aa(z);
aa(z1);
la(l);
}