1

我发现自己编写的代码看起来很多:

set<int> affected_items;
while (string code = GetKeyCodeFromSomewhere())
{
    if (code == "some constant" || code == "some other constant") {
        affected_items.insert(some_constant_id);
    } else if (code == "yet another constant" || code == "the constant I didn't mention yet") {
        affected_items.insert(some_other_constant_id);
    } // else if etc...
}
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++)
{
    switch(*it)
    {
        case some_constant_id:
           RunSomeFunction(with, these, params);
        break;
        case some_other_constant_id:
           RunSomeOtherFunction(with, these, other, params);
        break;
        // etc...
    }
}

我最终编写此代码的原因是我只需要运行第二个循环中的函数一次,即使我收到了多个可能导致它们运行的​​关键代码。

这似乎不是最好的方法。有没有更简洁的方法?

4

4 回答 4

2

一种方法是维护从字符串到布尔值的映射。主要逻辑可以从以下内容开始:

if(done[code])
    continue;
done[code] = true;

然后,您可以在识别代码后立即执行适当的操作。

另一种方法是将某些可执行文件(对象、函数指针等)存储到某种“待办事项列表”中。例如:

while (string code = GetKeyCodeFromSomewhere())
{
    todo[code] = codefor[code];
}

为每个代码值初始化 codefor 以包含适当的函数指针或从公共基类子类化的对象。如果相同的代码多次出现,则 todo 中的相应条目将被其已有的相同值覆盖。最后,遍历 todo 并运行它的所有成员。

于 2008-10-28T01:46:43.493 回答
1

由于您似乎并不关心集合中的实际值,因此您可以将其替换为 int 中的设置位。您还可以将线性时间搜索逻辑替换为日志时间搜索逻辑。这是最终的代码:

// Ahead of time you build a static map from your strings to bit values.
std::map< std::string, int > codesToValues;
codesToValues[ "some constant" ] = 1;
codesToValues[ "some other constant" ] = 1;
codesToValues[ "yet another constant" ] = 2;
codesToValues[ "the constant I didn't mention yet" ] = 2;

// When you want to do your work
int affected_items = 0;
while (string code = GetKeyCodeFromSomewhere())
    affected_items |= codesToValues[ code ];

if( affected_items & 1 )
    RunSomeFunction(with, these, params);
if( affected_items & 2 )
    RunSomeOtherFunction(with, these, other, params);
// etc...
于 2008-10-28T01:29:57.490 回答
1

它当然不是更整洁,但您可以维护一组标志,说明您是否调用了该特定函数。这样,您就不必将东西保存在一组中,您只需拥有标志。

由于存在(可能从它的编写方式),在编译时固定数量的不同 if/else 块,您可以使用 bitset 轻松完成此操作。

于 2008-10-28T01:30:14.963 回答
0

显然,这将取决于具体情况,但最好让您调用的函数跟踪它们是否已经运行并在需要时提前退出。

于 2008-10-28T03:41:22.640 回答