什么是预处理器宏有用?

xto*_*ofl 2 c++ macros

阅读另一个问题关于使用宏后,我在想:什么他们好?

我很快就会看到被其他语言构造取代的一件事是减少你需要在下面输入的相关单词的数量:

void log_type( const bool value ) { std::cout << "bool: " << value; }
void log_type( const int value ) { std::cout << "int: " << value; }
...
void log_type( const char  value ) { std::cout << "char: "  << value; }
void log_type( const double  value ) { std::cout << "int: "  << value; }
void log_type( const float  value ) { std::cout << "float: "  << value; }
Run Code Online (Sandbox Code Playgroud)

而不是

#define LOGFN( T ) void log_type( const T value ) { std::cout << #T ## ": " << value; }
LOGFN( int )
LOGFN( bool )
...
LOGFN( char )
LOGFN( double )
LOGFN( float )
Run Code Online (Sandbox Code Playgroud)

还有其他"不可替代的"吗?

编辑:试图总结原因 - 为什么在答案中遇到; 因为那是我感兴趣的东西.主要是因为我有一种感觉,他们中的大部分是由于我们仍然在原始文本文件中编程,仍然是支持不佳的环境.

  • 代码编译的灵活性(例如#ifdef DEBUG,平台问题)(SadSido,Catalin,Goz)
  • 调试目的(例如__LINE__, __TIME__); 我也根据这个原因设置'字符串'(SadSido,Jla3ep,Jason S)
  • 替换例如PHP requireinclude特征(#pragma once)(SadSido,Catalin)
  • 通过更换复杂的代码可读性增强(例如MESSAGEMAP,BOOST_FOREACH)(SadSido,fnieto)
  • 干原则(杰森S)
  • 内联替换(Matthias Wandel,Robert S. Barnes)
  • stringifying(杰森S)

Sad*_*ido 14

  • 在不同的条件下编译不同的代码(#ifdef __DEBUG__);
  • 保护每个翻译单元包含一个标题(#pragma once);
  • __FILE____LINE__- 替换为当前文件名和当前行;
  • 构造代码以使其更具可读性(例如:)BEGIN_MESSAGE_MAP();

在这里看到有趣的宏观讨论:

http://www.gotw.ca/gotw/032.htm

http://www.gotw.ca/gotw/077.htm

  • BEGIN_MESSAGE_MAP只是隐藏了MFC中Microsoft消息处理实现中的编码恐怖. (2认同)

Căt*_*tiș 7

最有用的 - 头文件保护:

#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD

// Header file content.

#endif 
Run Code Online (Sandbox Code Playgroud)

稍后添加[ 仅限Windows ]

将类导出到DLL:

#ifdef EXPORT_MY_LIB
#define    MY_API __declspec( dllexport)
#else
#define    MY_API __declspec( dllimport)
#endif
Run Code Online (Sandbox Code Playgroud)

样本类:

class MY_API MyClass { ... };
Run Code Online (Sandbox Code Playgroud)


Goz*_*Goz 7

平台特定部分.

#ifdef WINDOWS
#include "WindowsImplementation.h"
#elif defined( LINUX )
#include "LinuxImplementation.h"
#else
#error Platform undefined.
#endif
Run Code Online (Sandbox Code Playgroud)

  • 我认为这应该由构建系统处理,而不是由语言处理. (4认同)
  • 应该通过分层架构实现可移植性.一方面有一个没有#ifdef的接口,另一方面有这个接口的实现.在某些情况下(比如Windows/Unix),最好使用构建环境来选择正确的文件(如果私有部分需要某些特定于平台的类型,最终可以使用接口的平台版本).在其他(Unix变体)中,有很多共同点,使用条件编译处理是有意义的. (3认同)