gpt4 book ai didi

c++ - 如何在调用其他函数的 const 和非常量函数之间重用代码

转载 作者:可可西里 更新时间:2023-11-01 16:39:30 25 4
gpt4 key购买 nike

在这个示例代码中,两个 process() 函数中的循环是重复的。唯一的区别是一个是 const 而另一个不是。

有没有办法去除代码重复,使循环只存在一次?这只是一个示例,但在实际代码中,循环非常复杂,因此出于维护原因,我希望循环只存在一次。

#include <iostream>
#include <vector>

typedef unsigned int Item;
typedef std::vector<Item *> Data;

struct ReadOnlyAction {
void action(const Item *i)
{
// Read item, do not modify
std::cout << "Reading item " << *i << "\n";
}
};

struct ModifyAction {
void action(Item *i)
{
// Modify item
std::cout << "Modifying item " << *i << "\n";
(*i)++;
}
};

void process(Data *d, ModifyAction *cb) {
// This loop is actually really complicated, and there are nested loops
// inside it three levels deep, so it should only exist once
for (Data::iterator i = d->begin(); i != d->end(); i++) {
Item *item = *i;
cb->action(item);
}
}

void process(const Data *d, ReadOnlyAction *cb) {
// This is the same loop as above, and so the code should not be duplicated
for (Data::const_iterator i = d->begin(); i != d->end(); i++) {
const Item *item = *i;
cb->action(item);
}
}

void incrementData(Data *d) {
// Here we modify the pointer, and need to loop through it
ModifyAction incrementItem;
process(d, &incrementItem);
}

void saveData(const Data *d) {
// Here we aren't allowed to modify the pointer, but we still need
// to loop through it
ReadOnlyAction printItem;
process(d, &printItem);
}

int main(void)
{
Data d;
// Populate with dummy data for example purposes
unsigned int a = 123;
unsigned int b = 456;
d.push_back(&a);
d.push_back(&b);

incrementData(&d);
saveData(&d);

return 0;
}

请注意,这不是一个重复的问题。以下类似的问题和答案是不同的:

  • 123758 - 仅涵盖返回值的简单函数,而此函数会调用其他函数,因此此处给出的解决方案不适用于此问题
  • 23809745 - 相同的问题,仅涵盖返回值的简单函数,答案不适用于此问题

如果我尝试这些答案中给出的解决方案,它不起作用但看起来像这样:

template <class CB>
void processT(const Data *d, CB *cb) {
// Single loop in only one location
for (Data::const_iterator i = d->begin(); i != d->end(); i++) {
const Item *item = *i;

// Compilation fails on the next line, because const Item* cannot be
// be converted to Item* for the call to ModifyAction::action()
cb->action(item);
}
}

void process(const Data *d, ReadOnlyAction *cb) {
processT(d, cb);
}
void process(Data *d, ModifyAction *cb) {
processT(static_cast<const Data *>(d), cb);
}

这是一个简化的例子,所以如果答案可以集中在问题上(如何从两个 process() 函数中删除重复的循环)而不是评论设计 - 对设计的更改当然很好,如果它删除了过程中的重复循环。

最佳答案

尝试这样的事情:

template <class IteratorType, class CB>
void processT(IteratorType first, IteratorType last, CB *cb)
{
while (first != last)
{
cb->action(*first);
++first;
}
}

void process(const Data *d, ReadOnlyAction *cb)
{
Data::const_iterator first = d->begin();
Data::const_iterator last = d->end();
processT(first, last, cb);
}

void process(Data *d, ModifyAction *cb)
{
Data::iterator first = d->begin();
Data::iterator last = d->end();
processT(first, last, cb);
}

当然,在这个简化的示例中,您可以只使用 std::for_each() 代替:

#include <algorithm>

void process(const Data *d, ReadOnlyAction *cb)
{
std::for_each(d->begin(), d->end(), &cb->action);
}

void process(Data *d, ModifyAction *cb)
{
std::for_each(d->begin(), d->end(), &cb->action);
}

关于c++ - 如何在调用其他函数的 const 和非常量函数之间重用代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26028520/

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