C++ 宏将后续代码带出命名空间

C++ Macro takes proceeding code to be out of namespace

目前我有一个程序需要为许多功能进行属性打包。代码必须可以在 Windows Visual Studio C++ 和 GCC C++ 之间互换。目前它很难阅读,我想用 C++ 宏清理它,但是,我注意到在我使用宏一次后,下一行代码退出当前命名空间。有没有办法来解决这个问题?这是类似于我正在处理的示例代码和问题的图像。

#if defined(_WIN32) || defined(_WIN64)
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#else
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif

namespace test {
  PACK(typedef struct temp1 {
    int a;
    int b;
  });

  PACK(typedef struct temp2 {
    int c;
    int d;
  });
}

在visual studio中,当我的光标在第一个结构中时,VS 显示它在名称空间测试中,然而,第二个在全局名称空间中。关于如何解决这个问题的任何想法?

到目前为止,我的结构看起来更像下面的代码,它可以工作,但它使阅读变得更加困难,尤其是对于 100 多个这样的打包结构。

#define PACK __attribute__((__packed__))

namespace test {
  #if defined(_WIN32) || defined(_WIN64)
  #pragma pack(push, 1)
  #endif
  typedef struct temp1 {
    int a;
    int b;
  }
  #if defined(_WIN32) || defined(_WIN64)
  temp2;
  #pragma pack(pop)
  #else
  PACK temp2;
  #endif

  #if defined(_WIN32) || defined(_WIN64)
  #pragma pack(push, 1)
  #endif
  typedef struct temp2 {
    int c;
    int d;
  }
  #if defined(_WIN32) || defined(_WIN64)
  temp2;
  #pragma pack(pop)
  #else
  PACK temp2;
  #endif
}

在 C++ 中不需要 typedef struct 声明。只有在 C 中才需要,如果您不想在每个地方都使用 struct 关键字,则使用结构 type(变量、函数参数等)。

在 Visual Studio 中,在第一个 struct 声明之前放置一个 #pragma pack(push, 1) 并在最后一个 [=12] 之后放置一个 #pragma pack(pop) 会更容易=]声明。您不需要单独打包结构。

在 GCC 上,您可以跳过 #pragma 并在每个 struct 声明中使用 __attribute__((packed))

试试像这样的东西:

#ifdef __GNUC__
#define PACKED_ATTR __attribute__ ((__packed__))
#else
#define PACKED_ATTR
#endif

namespace test {
  #ifdef _MSC_VER
  #pragma pack(push, 1) // or: #include <pshpack1.h>
  #endif

  struct PACKED_ATTR temp1 {
    int a;
    int b;
  };

  struct PACKED_ATTR temp2 {
    int c;
    int d;
  };

  // and so on ...

  #ifdef _MSC_VER
  #pragma pack(pop) // or: #include <poppack.h>
  #endif
}