简体   繁体   English

在给定命名声明的宏中使用变量声明的类型

[英]Use type of variable declaration inside macro given named declaration

I've got a large C++20 codebase with a bunch of macro instantiations that are simple variations of this example:我有一个大型 C++20 代码库,其中包含一堆宏实例化,这些宏实例化是这个示例的简单变体:

void main() {
  MAKE_VAR(int myInt);
  MAKE_VAR(CMyClass myClass);
  MAKE_VAR(CMyClass *pMyClass);
};

Because the utility of the macro is part of a process that exists outside of the actual compilation of the code, the #define is currently trivial:因为宏的实用程序是存在于代码实际编译之外的过程的一部分,所以#define目前是微不足道的:

#define MAKE_VAR(var) var

Which means the resulting code after expansion is simply:这意味着扩展后的结果代码很简单:

void main() {
  int myInt;
  CMyClass myClass;
  CMyClass *pMyClass;
};

But, I'm trying to add more smarts to MAKE_VAR that depends upon the type of the variable, and for compatibility reasons I'm unable to change that macro signature (eg having the macro take the type and name as separate arguments).但是,我正在尝试向MAKE_VAR添加更多智能,这取决于变量的类型,并且出于兼容性原因,我无法更改该宏签名(例如,让宏将类型和名称作为单独的参数)。

So, my question is whether or not there is some incantation whereby I can take the var macro argument and produce just the type of that argument for use as a template parameter in a subsequent bit of generated code.所以,我的问题是是否有一些咒语,我可以使用var宏参数并只生成该参数的类型,以在随后生成的代码中用作模板参数。 Note that I do not need to get the name out (nor do I believe that's possible with standard C++20).请注意,我不需要说出这个名字(我也不相信标准 C++20 可以做到这一点)。

That is, I would like to come up with a macro definition such that the above MyStruct example expands into something like this (with whatever extra boilerplate necessary):也就是说,我想提出一个宏定义,以便上面的MyStruct示例扩展为类似这样的内容(需要任何额外的样板文件):

void main() {
  int myInt;
  DoThing<int>();

  CMyClass myClass;
  DoThing<CMyClass>();

  CMyClass *pMyClass;
  DoThing<CMyClass *>();
};

My first attempts revolved around trying to get something I could pass into decltype , but I wasn't able to find any such incantation that permits the name being present.我的第一次尝试围绕着试图获得一些我可以传递给decltype的东西,但我找不到任何允许该名称存在的咒语。

I've gotten close to a solution with the following approach but I have a different problem, where it only works once (because FakeFunc doesn't have a unique name per instance - normally I would use something akin to __COUNTER__ or similar but I need it to work across both lines here):我已经接近使用以下方法的解决方案,但我有一个不同的问题,它只能工作一次(因为FakeFunc每个实例没有唯一的名称 - 通常我会使用类似于__COUNTER__或类似的东西,但我需要它在这里跨两条线工作):

template <typename Sig> struct ArgType;
template <typename Arg> struct ArgType<void(Arg)> { using type = Arg; };

#define MAKE_VAR(var) \
  var; \
  typedef void FakeFunc( var ); \
  DoThing<typename ArgType<FakeFunc>::type>();

void main() {
  MAKE_VAR(int myInt);
  MAKE_VAR(unsigned myUInt);
};

// Macro expands to:
void main() {
  int myInt;
  typedef void FakeFunc( int myInt );
  DoThing<typename ArgType<FakeFunc>::type>();

  unsigned myUInt;
  typedef void FakeFunc( unsigned myUInt );
  DoThing<typename ArgType<FakeFunc>::type>();
};

Any thoughts on finishing out this approach or using a different approach?关于完成这种方法或使用不同方法的任何想法?

EDIT: Closing question for now because I need to clarify why I can't just put FakeFunc and DoThing in a local scope, which is a nuance I didn't capture in this simplified question...编辑:现在结束问题,因为我需要澄清为什么我不能将FakeFuncDoThing放在本地 scope 中,这是我在这个简化问题中没有捕捉到的细微差别......

You don't need to give a name to the function:您无需为 function 命名:

template <typename Sig> struct ArgType;
template <typename Arg> struct ArgType<void(*)(Arg)> { using type = Arg; };

template <typename T> void DoThing() {}

#define MAKE_VAR(var) \
  var; \
  DoThing<typename ArgType<void (*)( var )>::type>();

int main() {
        MAKE_VAR(int x)
        MAKE_VAR(unsigned y)
}

Live Demo现场演示

The macros expand to宏扩展为

int x; DoThing<typename ArgType<void (*)( int x )>::type>();
unsigned y; DoThing<typename ArgType<void (*)( unsigned y )>::type>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM