【问题标题】:C++ - Are there ways to get current class type with invariant syntax? [duplicate]C++ - 有没有办法用不变的语法来获取当前的类类型? [复制]
【发布时间】:2015-10-20 07:36:07
【问题描述】:

我想编写一个宏,当在一个类中展开时,它使用该类类型(特别是作为模板参数)。在类方法中,我可以使用这个:

#define METHOD_MACRO int sample_method(void)const {\
    return template_struct<this_type<decltype(this)>::type>::index;}

(this_type 是我的结构体,这里相当于remove_pointer&lt;remove_const&lt;T&gt;&gt;)

但是当我需要方法之外的类类型时(对于类成员指针的 typedef),this 关键字不可用;我尝试使用auto 进行一些推断类型的技巧,但这里没有运气。 有问题的类是从我的类继承的,如果这有帮助的话。我想避免任何使用我的宏的人都必须写typdedef

有什么想法吗?

【问题讨论】:

  • 使用 CRTP?也许您可以完全消除宏...
  • 这需要用户做出明确的努力,我尽量避免。有趣的想法,但还不够。
  • @Abstraction 键入宏的名称需要用户做出的明确努力,而不是从具有 CRTP 的类继承:)
  • @Drax 仍然存在覆盖虚函数的问题,但是是的,这是可能的解决方案(并且比要求“typedef Class self”等更优雅)。这对用户来说没有多大意义——必须像这样写两次类名。
  • @Petr - 是的,它是一样的。搜了一下没找到,不好意思。不过,感谢您的帮助 - 即使您的解决方案依赖于编译器,这可能就足够了。

标签: c++ templates c++11


【解决方案1】:

您可以使用以下技巧:

#define SELF \
    static auto helper() -> std::remove_reference<decltype(*this)>::type; \
    typedef decltype(helper()) self

struct A {
    SELF;
};

我使用auto 返回类型声明了一个辅助函数,它允许我使用decltype(*this) 作为返回类型,而不知道类名是什么。然后我可以使用decltype(helper()) 来使用代码中的类类型。注意函数必须是static,否则不能在decltype中使用。该函数也是刚刚声明的,没有定义;这应该不是问题,因为无论如何您都不会调用它。 (你可以给它添加一个空的body,但是它会引发一个函数没有return的警告。你仍然可以将返回类型更改为decltype(this)并返回nullptr。)

然后您可以使用self typedef 进行进一步的声明,或者只是将宏更改为 typedef,而不是类本身,而是您需要的。调整它以满足您的特定需求。

UPD:这似乎是 GCC 的非标准行为。例如,ICC 不允许在 static 函数中使用 this,即使在尾随返回类型中也是如此。

【讨论】:

  • 为什么可以在这种情况下使用this
  • @n.m.,为什么我不能?我不是标准的专家,但我粗略的理解是this只是一个隐式函数参数,我可以在返回类型中使用函数参数auto。它确实有效:coliru.stacked-crooked.com/a/9af8022707a13ff6
  • @n.m.,尽管我只是认为在 static 函数中包含 this 确实很奇怪。最初试图使其成为非静态的,添加static 以使decltype(helper()) 工作,并没有意识到decltype(*this) 可能会中断。无论如何,它有效。不要说是 GCC 的 bug :)
  • @n.m.,有趣的是,GCC 似乎允许在 尾随返回类型 中使用decltype(*this),但不能在函数体中使用,对此我找不到任何解释。可能很快就会提出一个单独的问题。
  • 是的,这看起来像一个 gcc 错误。
猜你喜欢
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多