Typedef 到 C++ 中的周围类型

Posted

技术标签:

【中文标题】Typedef 到 C++ 中的周围类型【英文标题】:Typedef to surrounding type in C++ 【发布时间】:2016-01-27 09:51:35 【问题描述】:

有没有办法在类型声明中为声明的(周围)类型本身构建typedef,而不用说明类型的名称?

例子:

class X

  public:
    typedef <fill in magic here> MyType;
  //...
;

背景: 乍一看,这似乎很愚蠢。我需要这个,因为我使用宏构建了我的数据类的编译时反射。 所以在数据类的声明中插入了一个宏,该宏需要处理它插入的类型。 到目前为止,我找到了 MSVC 和 g++ 的工作解决方案,它们都依赖于我认为的实现中的缺陷。所以他们可能无法在较新的版本上工作。 Clang 不会“吃掉”这些解决方案中的任何一个。

我当前的 MSVC 解决方案定义了一个方法,然后仅通过它的名称获取它的地址,并调用一个“返回”其类的类型的小助手。 (Clang 和 g++ 需要方法的全名,包括它的类名)。

我当前的 g++ 解决方案定义了一个返回类型为 std::remove_reference(decltype(*this)) 的静态方法。 (Clang 和 MSVC 不允许在静态上下文中使用 this)。

我绝对更喜欢标准的一致性解决方案,但目前也可以使用特殊的 clang 解决方案。

如果没有任何效果,我必须将类的名称传递给宏,但我尽量避免这种情况,因为我已经有大量使用宏的代码。

编辑:添加一个关于反射如何工作的示例(这可能会阐明我需要什么):

class X : public Y

  public:
    //.. constructor and such stuff...

    int a;
    double b;
    std::string c;

    CLASSHEAD(Y)
      FIELD(a)
      FIELD(b)
      FIELD(c)
    CLASSFOOT
;

CLASSHEAD 是应该定义typedef 的宏。它是一个 VAR_ARGS 宏,其中参数接收基类。如前所述:可以将类的名称作为它的第一个参数(在示例中导致CLASSHEAD(X, Y))。但我几乎无法想象对于像 typedef'ing 周围类型这样的“简单”任务没有解决方案......

【问题讨论】:

实际上,我并不清楚为什么你不能只做typedef X MyType;,然后让宏使用MyType 我认为需要这个的唯一原因是函数签名。在函数本身中,您将使用上述typedef std::remove_reference(decltype(*this))::type MyType;。你可以制作这些函数模板,然后static_assert(std::is_same&lt;T, MyType&gt;::value);。不漂亮,想不出更好的了。 恐怕要获得符合标准的解决方案,您必须等到新标准准备好进行类型反射(在您的情况下是自省)。见open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3814.html 似乎这样做的方法是定义一个创建类声明的宏。类名将是宏的参数,然后它将发出public CLASSNAME MyType; 行。 Similar question 【参考方案1】:

这并不完全符合您的规范,但我认为它非常接近:

class X

//Stuff...

//Use Macros to add:
struct MyType;

//Use class closing macro to insert variable between class-ending brace and semicolon      


 TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType

    typedef decltype(TYPE_VAR) V;
;

然后访问 X 的类型使用

X::MyType::V

例如,简化的 CLASSFOOT 可能如下所示:

#define CLASSFOOT /*Your classfoot here*/  TYPE_VAR; struct decltype(TYPE_VAR)::MyType typedef decltype(TYPE_VAR) V;
//No ; at end on purpose- this will come from the class in which you placed CLASSFOOT

这足以满足您的目的吗?

【讨论】:

缺点是 MyType::V 不能在 X 的定义中使用(我认为 OP 需要的功能) 这没有回答原来的问题。【参考方案2】:

由于您已经在使用宏,您可以使用此解决方案https://***.com/a/21143997/2173029

#define CLASS_WITH_MY_TYPE(ClassName) \ 
    class ClassName                   \
                                     \
       using MyType = ClassName;

然后用like

CLASS_WITH_MY_TYPE(X)
public:
  struct Y
  
    using T = MyType;
  ;
;

static_assert(std::is_same<X, typename X::Y::T>::value, "");

标记为社区 wiki,因为@Chris 提到了链接并且原始答案由 @Bartek Banachewicz 发布

【讨论】:

@RüdigerStevens 我以为你的意思是 CLASSHEAD 宏。【参考方案3】:

Nohting 有效,因此在宏中使用类 Name 是唯一可行的解​​决方案

【讨论】:

以上是关于Typedef 到 C++ 中的周围类型的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中严格 typedef 的成语

关于C++ typedef list<类名>:iterator iterator;出错

如何解决 C++ 中的 typedef 重定义?

C++ typedef typename 作用

C++ 类 Typedef Struct 没有命名类型

C++ typedef用法详解