<bdo id='piqpi'></bdo><ul id='piqpi'></ul>

<i id='piqpi'><tr id='piqpi'><dt id='piqpi'><q id='piqpi'><span id='piqpi'><b id='piqpi'><form id='piqpi'><ins id='piqpi'></ins><ul id='piqpi'></ul><sub id='piqpi'></sub></form><legend id='piqpi'></legend><bdo id='piqpi'><pre id='piqpi'><center id='piqpi'></center></pre></bdo></b><th id='piqpi'></th></span></q></dt></tr></i><div id='piqpi'><tfoot id='piqpi'></tfoot><dl id='piqpi'><fieldset id='piqpi'></fieldset></dl></div>
<tfoot id='piqpi'></tfoot>

<legend id='piqpi'><style id='piqpi'><dir id='piqpi'><q id='piqpi'></q></dir></style></legend>

      <small id='piqpi'></small><noframes id='piqpi'>

      1. MSVC++ 可变参数宏扩展

        时间:2023-06-04
        • <tfoot id='2B4PD'></tfoot>

                <small id='2B4PD'></small><noframes id='2B4PD'>

                <i id='2B4PD'><tr id='2B4PD'><dt id='2B4PD'><q id='2B4PD'><span id='2B4PD'><b id='2B4PD'><form id='2B4PD'><ins id='2B4PD'></ins><ul id='2B4PD'></ul><sub id='2B4PD'></sub></form><legend id='2B4PD'></legend><bdo id='2B4PD'><pre id='2B4PD'><center id='2B4PD'></center></pre></bdo></b><th id='2B4PD'></th></span></q></dt></tr></i><div id='2B4PD'><tfoot id='2B4PD'></tfoot><dl id='2B4PD'><fieldset id='2B4PD'></fieldset></dl></div>

                <legend id='2B4PD'><style id='2B4PD'><dir id='2B4PD'><q id='2B4PD'></q></dir></style></legend>
                  <bdo id='2B4PD'></bdo><ul id='2B4PD'></ul>
                    <tbody id='2B4PD'></tbody>
                  本文介绍了MSVC++ 可变参数宏扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  所以我有一个在 GCC 中运行良好的宏,但在 Microsoft 的 C++ 编译器中不起作用.我希望有人可能知道一种解决方法,或者可以向我解释为什么它会这样.

                  So I've got a macro that works nicely in GCC, but not in Microsoft's C++ Compiler. I'm hoping somebody might know of a workaround, or perhaps can explain to me why it behaves this way.

                  我确定这个宏并不完全是标准的",但它确实对我有帮助.

                  I'm sure this macro isn't exactly "standard", but it would really help me out.

                  这是宏的功能示例:

                  #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
                  #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
                  
                  #define FULLY_EXPANDED(count, ...) 
                    MAC ## count (__VA_ARGS__)
                  
                  #define SEMI_EXPANDED(count, ...) FULLY_EXPANDED(count, __VA_ARGS__)
                  
                  #define EXPAND_THESE(...) SEMI_EXPANDED(VA_NARGS(__VA_ARGS__), __VA_ARGS__)
                  
                  #define ACTUAL_MACRO(x) parent->GetProperty<x>();
                  #define MAC1(a) ACTUAL_MACRO(a)
                  #define MAC2(a,b) MAC1(a) ACTUAL_MACRO(b)
                  #define MAC3(a,b,c) MAC2(a,b) ACTUAL_MACRO(c)
                  #define MAC4(a,b,c,d) MAC3(a,b,c) ACTUAL_MACRO(d)
                  #define MAC5(a,b,c,d,e) MAC4(a,b,c,d) ACTUAL_MACRO(e)
                  

                  这里是我可以使用这个宏的方法:

                  Here is how I might use this macro:

                  struct MyStructure
                  {
                    void Foo()
                    {
                      EXPAND_THESE(Property1, Property2, Property3, Property4)
                    }
                  
                    Base * parent;
                  }
                  

                  以下是 GCC 如何扩展上述内容:

                  Here's how GCC expands the above:

                  struct MyStructure
                  {
                    void Foo()
                    {
                      parent->GetProperty<Property1>(); 
                      parent->GetProperty<Property2>(); 
                      parent->GetProperty<Property3>(); 
                      parent->GetProperty<Property4>();
                    }
                  
                    Base * parent;
                  }
                  

                  但微软出于某种原因将我所有的 __VA_ARGS__ 扩展为一个参数:

                  But Microsoft for some reason expands all my __VA_ARGS__ as one argument:

                  struct MyStructure
                  {
                    void Foo()
                    {
                      parent->GetProperty<Property1, Property2, Property3, Property4>();
                    }
                  
                    Base * parent;
                  }
                  

                  有人知道这是为什么吗?有什么技巧可以让微软像 GCC 一样扩展它吗?也许多加几对括号?

                  Does anybody know why this is? Is there some trick I can pull to get Microsoft to expand this like GCC? Maybe toss in a couple extra pairs of parentheses?

                  像这样的宏确实可以帮助我替换一堆胶水"代码,但是由于这个问题,我无法将其移动到我的 VS 项目中.任何帮助将不胜感激!

                  Macros like this could really help me out in replacing a bunch of "glue" code, but because of this problem, I can't move it into my VS project. Any help would be greatly appreciated!

                  谢谢.

                  推荐答案

                  巧合的是,我今天刚好遇到了这个问题,经过足够的努力,我想我已经找到了适合自己的解决方案.错误是 MSVC 将 __VA_ARGS__ 视为参数列表中的单个标记.但是您可以通过不在宏调用参数列表中直接使用它来解决此问题.此评论 建议开始回答您的问题:

                  Coincidentally, I happened to run into this problem just today, and after enough effort I think I've found a solution for my own purposes. The bug is MSVC treats __VA_ARGS__ as a single token in argument lists. But you can work around this by not using it directly within a macro call argument list. This comment suggests the start of an answer to your problems:

                  #define VA_NARGS(...) VA_NUM_ARGS_IMPL_((__VA_ARGS__, 5,4,3,2,1))
                  #define VA_NARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
                  #define VA_NARGS_IMPL(_1,_2,_3,_4,_5,N,...) N
                  

                  但是我怀疑您可能会遇到确保完全扩展到您想要的实际N"的问题,而不是 VA_NARGS_IMPL (arg1, arg2, 5, 4, 3, 2, 1) ,比如说.我发现我的代码(看起来像你的)必须更改以将 MAC##code 全部扩展为一个单元,然后必须将其与参数列表分开组合.这是我发现对我有用的代码:

                  But then I suspect you'll likely run into the issue of making sure that gets fully expanded to the actual "N" you want, and not to VA_NARGS_IMPL (arg1, arg2, 5, 4, 3, 2, 1), say. I found that my code (which looked like yours) had to change to expand MAC##code all as one unit, and then that had to be separately combined with the argument list. Here's the code that I found worked for me:

                  #define ASSERT_HELPER1(expr) singleArgumentExpansion(expr)
                  #define ASSERT_HELPER2(expr, explain) 
                     twoArgumentExpansion(expr, explain)
                  
                  /*
                   * Count the number of arguments passed to ASSERT, very carefully
                   * tiptoeing around an MSVC bug where it improperly expands __VA_ARGS__ as a
                   * single token in argument lists.  See these URLs for details:
                   *
                   *   http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement
                   *   http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644
                   */
                  #define COUNT_ASSERT_ARGS_IMPL2(_1, _2, count, ...) 
                     count
                  #define COUNT_ASSERT_ARGS_IMPL(args) 
                     COUNT_ASSERT_ARGS_IMPL2 args
                  #define COUNT_ASSERT_ARGS(...) 
                     COUNT_ASSERT_ARGS_IMPL((__VA_ARGS__, 2, 1, 0))
                   /* Pick the right helper macro to invoke. */
                  #define ASSERT_CHOOSE_HELPER2(count) ASSERT_HELPER##count
                  #define ASSERT_CHOOSE_HELPER1(count) ASSERT_CHOOSE_HELPER2(count)
                  #define ASSERT_CHOOSE_HELPER(count) ASSERT_CHOOSE_HELPER1(count)
                   /* The actual macro. */
                  #define ASSERT_GLUE(x, y) x y
                  #define ASSERT(...) 
                     ASSERT_GLUE(ASSERT_CHOOSE_HELPER(COUNT_ASSERT_ARGS(__VA_ARGS__)), 
                                 (__VA_ARGS__))
                  
                  int foo()
                  {
                    ASSERT(one); // singleArgumentExpansion(one)
                    ASSERT(two, "foopy"); // twoArgumentExpansion(two, "foopy")
                  }
                  

                  在解决了我自己的问题几个小时后,我的思绪太混乱了,无法完全解决你的问题,我很抱歉地说.:-) 但我认为这足以让你做一些有用的事情,只需做一点工作.

                  My mind is too much mush after a few hours solving my own issues to then go and completely solve yours, I'm sorry to say. :-) But I think this is enough to get you to something that works, with a little work.

                  这篇关于MSVC++ 可变参数宏扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:在任何情况下 new 都会返回 NULL 吗? 下一篇:无法将临时对象作为参考传递

                  相关文章

                • <legend id='J0Xz2'><style id='J0Xz2'><dir id='J0Xz2'><q id='J0Xz2'></q></dir></style></legend>
                • <small id='J0Xz2'></small><noframes id='J0Xz2'>

                    <i id='J0Xz2'><tr id='J0Xz2'><dt id='J0Xz2'><q id='J0Xz2'><span id='J0Xz2'><b id='J0Xz2'><form id='J0Xz2'><ins id='J0Xz2'></ins><ul id='J0Xz2'></ul><sub id='J0Xz2'></sub></form><legend id='J0Xz2'></legend><bdo id='J0Xz2'><pre id='J0Xz2'><center id='J0Xz2'></center></pre></bdo></b><th id='J0Xz2'></th></span></q></dt></tr></i><div id='J0Xz2'><tfoot id='J0Xz2'></tfoot><dl id='J0Xz2'><fieldset id='J0Xz2'></fieldset></dl></div>
                  1. <tfoot id='J0Xz2'></tfoot>
                    • <bdo id='J0Xz2'></bdo><ul id='J0Xz2'></ul>