2015-07-03 114 views
0

我讀boost's config/suffix.hpp,我用下面的代碼感到驚訝:BOOST_PREVENT_MACRO_SUBSTITUTION應該如何工作?

// Workaround for the unfortunate min/max macros defined by some platform headers 

#define BOOST_PREVENT_MACRO_SUBSTITUTION 

// <skipped unimportant lines> 

namespace std { 
    template <class _Tp> 
    inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { 
    return __b < __a ? __b : __a; 
    } 
    template <class _Tp> 
    inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { 
    return __a < __b ? __b : __a; 
    } 
} 

這實際上似乎是使minmax函數的定義編譯時的同名宏是一個有效的事情定義。但是,爲什麼這在實際的呼叫站點是有用的?當函數被調用時宏不會實際替代嗎?我試圖做一個簡單的測試,「模仿」這個設置:

#include <iostream> 

#define PREVENT_MACRO_SUBSTITUTION 
#define max(x,y) ((x)<(y)?(y):(x)) 

namespace test 
{ 
int max PREVENT_MACRO_SUBSTITUTION (int a, int b) 
{ 
    std::cerr << "Function max\n"; 
    return a<b?b:a; 
} 
} 

int main() 
{ 
    int x=test::max(5,6); 
    std::cout << "x="<<x<<"\n"; 
} 

而且,正如所料,我得到一個編譯錯誤由於max宏擴展。那麼,助推器的宏觀替代預防應該如何運作呢?

回答

3

它不應該做你認爲它應該做的事。

如果minmax宏定義,用戶希望調用這些std::minstd::max功能,這是用戶的責任,以確保宏被抑制。可能再次使用BOOST_PREVENT_MACRO_SUBSTITUTION,可能使用括號((std::min) (...))。

所有使用BOOST_PREVENT_MACRO_SUBSTITUTION在這裏做的是防止語法錯誤被上調的定義的std::minstd::max,就像你想通了。如果頭部使用了inline const _Tp& min (const _Tp& __a, const _Tp& __b),它會很高興地將min擴展爲宏,從而產生類似inline const _Tp& ((const _Tp& __a) < (const _Tp& __b) ? (const _Tp& __a) : (const _Tp& __b))的東西。但是如果代碼實際上沒有使用minmax,那麼包含該頭文件應該是無害的。