【问题标题】:How to call std::min() when min has been defined as a macro?当 min 被定义为宏时如何调用 std::min()?
【发布时间】:2011-11-18 23:04:30
【问题描述】:

min 已被定义为宏时,如何调用 std::min

【问题讨论】:

  • 无情地#undef min 并使用标准设施。

标签: c++ stl macros


【解决方案1】:
(std::min)(x,y)

min 周围的括号防止宏扩展。这适用于所有函数宏。

【讨论】:

  • @André:是的。在[n3290: 3.4.2] 中以调用这样的函数作为示例,很明显这会阻止宏扩展(C99 中的6.10.3/10;我相信 C90 中的措辞很接近。)
  • 纯粹出于好奇,有没有办法阻止简单的#define foo 5 宏的扩展,或者这种覆盖行为仅适用于函数?
【解决方案2】:

在 Windows 上,您需要在包含任何 Windows 头文件之前定义 NOMINMAX,最好在预编译头文件的开头。

【讨论】:

  • 酷!不便携,但我还是喜欢它; +1。 :)
  • @Mehrdad:包括 Windows 头文件已经是不可移植的。
  • @Andre:我同意,这正是我说我仍然喜欢它的原因..:P
  • 也可以在项目文件中使用 /D NOMINMAX 命令行选项。如果您没有 PCH,这是一个有用的选择。
【解决方案3】:

在您的代码中使用#undef min,在#include <> 指令之后。

#include <...> // bad header that defines `min` macro
#ifdef min
#undef min
#endif

// rest f code.

附录:如果您之后需要保留min 宏的值,您可以在某些编译器上使用不可移植的解决方案暂时禁用其定义。例如,微软的 C++ 编译器有一个push_macro pragma,它似乎也是supported by GCC

【讨论】:

  • 呃,我真的不能这样做,因为这会弄乱之后可能由于某种原因依赖于宏的一切......这是一个相当糟糕的黑客,不是一个真正的解决方案。 :\
  • @Mehrdad: min 作为一个宏,一开始就是一个 hack。最好避免它。如果您真的想要一个宏,请使用一个名为 MIN 的宏或其他不会发生冲突的宏。
  • @Mehrdad:改为发布临时禁用的解决方案。但是,没有可移植的解决方案,因为该语言明确指出,如果定义了宏,则文本替换由预处理器完成,并且在编译器看来已被替换。没有可用于区分 min 函数和 min 宏的 C++ 语言结构。
  • @hammar:问题在于您假设这是在 C++ 文件中。如果这是一个头文件,它会搞砸谁包含它,因为他们不希望发生这种情况。 (编辑:对于临时禁用,我想这可行,但我希望有更好的解决方案..)
【解决方案4】:

您可以通过以下方式避免宏定义:

  • #undef
  • 首先避免定义(通过 #define NOMINMAX 等配置或类似配置,或避免包含有问题的标头)

如果这些选项无法使用或您不想使用它们,您始终可以通过适当使用括号来避免调用类似函数的宏:

#include <algorithm>
#include <stdio.h>

#define min(x,y) (((x) < (y)) ? (x) : (y))

int main() 
{
    printf( "min is %d\n", (std::min)( 3, 5));  // note: the macro version of `min` is avoided
}

这是可移植的,并且从 C 的早期黑暗时代就开始工作。

【讨论】:

    【解决方案5】:

    我发现了其他几种方法:

    方法一:

    using std::min;
    min(a, b);   // uses either the macro or the function (don't add side effects!)
    

    方法二:

    #ifndef BOOST_PREVENT_MACRO_SUBSTITUTION
    #define BOOST_PREVENT_MACRO_SUBSTITUTION
    #endif
    
    ...
    std::min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 2017-11-17
      • 2018-02-11
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      相关资源
      最近更新 更多