从#define到功能

时间:2015-03-20 00:07:46

标签: c++ c

我在函数中有这个代码,但我无法理解它的作用。

....
#define ascend(i) do {\
            int h = nodes[i].heavyindex;\
            int p = nodes[i].heavypos;\
            m##i = max(m##i + paths[h].ftree.sum(p), paths[h].stree.max_(0, p));\
            i = paths[h].parent;\
        } while (0)
    while (nodes[a].heavyindex != nodes[b].heavyindex) {
        if (nodes[a].heavyindex > nodes[b].heavyindex) {
            ascend(a);
        } else {
            ascend(b);
        }
    }
#undef ascend
...

我认为#define的代码是:

#define ascend(i) do {\
            int h = nodes[i].heavyindex;\
            int p = nodes[i].heavypos;\
            m##i = max(m##i + paths[h].ftree.sum(p), paths[h].stree.max_(0, p));\
            i = paths[h].parent;\
        } while (0)

所以函数中的实际代码只有这个:

while (nodes[a].heavyindex != nodes[b].heavyindex) {
        if (nodes[a].heavyindex > nodes[b].heavyindex) {
            ascend(a);
        } else {
            ascend(b);
        }
    }

1)这是对的吗? 2)我想在函数内部移动#define的代码以更好地理解它的作用,但是我如何翻译以下行?

m##i = max(m##i + paths[h].ftree.sum(p), paths[h].stree.max_(0, p));\ 

1 个答案:

答案 0 :(得分:1)

  1. 正如Ben Voigt在评论中所提到的,##是令牌粘贴运算符。因此,定义#define f(i) m##i后,f(a)将扩展为maf(b)将扩展为mb等。

    由于这只能在预处理器中实现,因此您必须考虑其他因素才能将其作为函数实现。通过引用传递mamb将是一个好主意。它可能看起来像这样:

    ascend(T& mi) {
        ...
        mi = max(mi + paths[h].ftree.sum(p), paths[h].stree.max_(0, p)); 
        ...
    }
    

    T的类型mamb。如果它们的类型不同,则需要将其设为功能模板。