【问题标题】:'this' pointer in macro and function宏和函数中的“this”指针
【发布时间】:2010-06-20 20:02:23
【问题描述】:

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

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

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

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

编译器将此代码插入到调用此宏的类中,因此“this”从调用者那里获取。但我不想使用宏并且更喜欢函数(内联)。但是如何解决“这个”传递。我可以像在宏中那样在内联函数中使用它还是必须手动传递它?

【问题讨论】:

    标签: c++ macros inline this


    【解决方案1】:

    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&lt;T&gt;,这是一个安全的演员表


    我个人更喜欢这个而不是宏。请注意,您的宏无法处理类型名称中的逗号

    DO(std::pair<A, B>, g);
    

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

    【讨论】:

    • 似乎你给this 赋予了与原始代码中完全不同的含义。 C++ 没有像 upvar icsi.berkeley.edu/~sather/Documentation/Gui/TclTkDocs/TclCmd/… 这样的东西
    • @Ben 我不知道 Tcl,但我所做的并没有改变 this 的值:插入中间函数调用不会影响它的值。在原始代码中,this 指的是当前对象,在我的代码中也是如此。请注意,我不建议将doit 传递给bind。但我建议通过调用doit 来替换宏调用。
    • @Noah 通常,一旦您发现自己弄错了,就会撤回您的反对票,或者评论您保留反对票的原因
    • @Noah:你想让他在访问它之前检查每个指针是否为NULL吗?不安全结构的安全使用是每个 C++ 应用程序所固有的。
    • +1:令人着迷。我不知道你可以使用 C 风格的转换静态转换到一个不可访问的基础。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      相关资源
      最近更新 更多