宏观和功能中的'this'指针

时间:2010-06-20 20:02:23

标签: c++ macros inline this

我有一些代码使用调用此代码的类的'this'指针。例如:

Some::staticFunction<templateType>(bind(FuncPointer, this, _1));

这是我从boost调用bind函数。但没关系。现在我必须包装此代码。我做了一个宏:

#define DO(Type, Func) Some::staticFunction<Type>(bind(FuncPointer, this, _1));

编译器将此代码插入到调用此宏的类中,因此'this'来自调用者。但我不想使用宏和首选功能(内联)。但如何解决'这'传递。我可以像在宏中一样在内联函数中使用它,或者我必须手动传递它吗?

2 个答案:

答案 0 :(得分:5)

this关键字可由您调用的函数

放置
class MyClass {
  // ...
  template<typename Type, typename Func>
  void doit(Func f) {
    Some::staticFunction<Type>(bind(f, this, _1));
  }
};

之后你可以打电话

doit<templateType>(FuncPointer);

如果您愿意,可以继承该功能

// T must be a derived class of MyRegister<T>
template<typename T>
class MyRegister {
protected:
  template<typename Type, typename Func>
  void doit(Func f) {
    Some::staticFunction<Type>(bind(f, (T*)this, _1));
  }
};

class MyClass : MyRegister<MyClass> {
  // ...
};

这样你就可以使用doit而不是先写它,就像使用宏一样。如果您有多种类可以使用该函数,则非常有用。

编辑:请注意,由于私有继承,此处的C样式强制转换必需(不能使用static_cast)。如果T来自MyRegister<T>

,则为安全演员

就个人而言,我更喜欢这个。请注意,您的宏无法处理类型名称

中的逗号
DO(std::pair<A, B>, g);

这会尝试将3个参数传递给宏而不是2.您可以反转类型和函数的顺序并使用可变参数宏(这是一个C ++ 0x特性,但在C ++中的某些编译器中可用) 03模式)或者您可以使用typedef并传递别名。

答案 1 :(得分:3)

内联函数是常规函数,必须自行编译。对于优化原因,inline关键字只是编译器的 建议 ,用于将实际函数体放到调用函数的位置。 具体而言,内联函数无法访问仅在调用位置可见的名称(在您的情况下为“this”),因此您必须将它们作为参数传递。

另一方面,宏只是在预处理时发生的文本扩展,因此宏体不需要自己具有意义,只要 final 您最终得到的扩展是合法的C ++代码。

例如,你可以让一个宏“打开”一个for循环而另一个宏“关闭”它(显然内联函数无法做到的事情)。