2016-12-19 94 views
1

我用的是舊版本的GCC,所以我試圖執行一些有用的type_traits元素,如is_base_of和static_assert,像這樣:我的c + +代碼在宏+模板編譯失敗,爲什麼這個錯誤?

template <typename Base, typename Derived> 
struct my_is_base_of{ 
    struct Yes{char _;}; 
    struct No{char _[2];}; 
    static Yes _test(const Base*); 
    static No _test(void*); 
    static const bool value=sizeof(_test((Derived*)0))==sizeof(Yes); 
}; 

template<bool b>struct _static_assert_test{static char _;}; 
template<>struct _static_assert_test<false>{}; 
#define _static_assert(x) _static_assert_test<x>::_ 

struct Base{}; 
struct Derived : Base {}; 
struct C {}; 
#include<iostream> 
int main() 
{ 
    std::cout<<std::boolalpha<<my_is_base_of<Base,Derived>::value<<std::endl; 
    _static_assert(sizeof(int)==4); 
    _static_assert(my_is_base_of<Base,Derived>::value);//fails to compile 
    return 0; 
} 

那麼,在主要功能的第1行編譯並打印「真」。第二行也是如此。但第三行無法編譯。我的gcc 4.1.2說:

derive.cpp:22:54: error: macro "_static_assert" passed 2 arguments, but takes just 1

derive.cpp: In function ‘int main()’:

derive.cpp:22: error: ‘_static_assert’ was not declared in this scope

如何解決我的情況?非常感謝。

回答

3

值得注意的是,C++宏在編譯的解析階段之前展開,這是通過將宏的每個參數替換爲匹配的地方來完成的。 my_is_base_of<Base,Derived>::value在這裏被宏解釋爲兩個參數,因爲它使用逗號運算符:my_is_base_of<Base成爲第一個參數,Derived>::value成爲第二個參數。這種行爲的原因正是由於宏沒有(不能)執行解析,因此無法知道在模板參數的上下文中使用了逗號。要解決該問題,您需要將括號括起來:

_static_assert((my_is_base_of<Base,Derived>::value)); 

編譯沒有問題。

+2

可能值得一提的是預處理器發生在C++解析器之前,並且預處理器不能識別任何C++令牌。 –

相關問題