2013-07-23 32 views
10

在求職面試中,我被要求編寫一個元函數 ,它確定一個類型是否是一個指針。這是 我提出:如何在沒有C++的情況下編譯時間斷言11

template <typename T> 
struct is_pointer 
{ static const bool value = false; } 

template <typename T> 
struct is_pointer<T *> 
{ static const bool value = true; } 

然後,我被要求寫一元斷言,如果我的is_pointer功能不 做正確的事情,這將在編譯時失敗 。

當我使用static_assert時,他明確告訴我 我只能使用C++ 98標準。我怎樣才能做到這一點?

+8

我認爲在這一點上,你通過了「檢查看看你是否真的知道這門語言「的一部分,除非公司製作C++編譯器或其他東西。 –

回答

5

在你的情況

template <bool> struct assert; 
template <> struct assert<true> {}; 

就已經解決了這個問題:

assert<!is_pointer<char>::value>();  // valid 
assert<is_pointer<char *>::value>(); // valid 

assert<is_pointer<char>::value>();  // compilation error: 
             // use of incomplete class 
+0

這不是什麼SFINAE(解決方案是好的,但名稱被濫用)。 –

+0

這也僅限於可以創建類型對象的位置。爲了能夠在其他上下文中使用它,您必須創建假對象:'// namespace:assert myassert;' –

9

有不同的方法,常見的一種嘗試的typedef無效類型:

#define static_assert(condition) \ 
     typedef char assert ## __LINE__ [((condition)?1:-1)] 

這可以在大多數情況下使用,並且如果條件爲假,則會使編譯器跳閘,因爲它會嘗試鍵入a n無效類型(負數元素數組)。它可用於不同的環境:

// namespace level: 
static_assert(sizeof(int)==4); 
struct type { 
    // class level: 
    static_assert(sizeof(int)==4); 
    void f() { 
     // function level 
     static_assert(sizeof(int)==4); 
    } 
}; 
+3

這一個甚至可以在純C中使用:)但請注意,使用您當前的宏,typedef將始終按原樣'assert__LINE__';要將'__LINE__'擴展到實際的行號,您需要一箇中間的「加入」宏調用:[需要將兩個令牌粘貼在一起的宏需要做什麼?](http://www.parashift.com/c++-faq /macros-with-token-pasting.html) –

3

我會使用BOOST_STATIC_ASSERT。你可以看看代碼:boost/static_assert.hpp

這裏是一個非常簡化的版本,只給你一個想法:

#define JOIN(X, Y) DO_JOIN(X, Y) 
#define DO_JOIN(X, Y) X ## Y 

template<bool cond> 
struct Static_assert_helper; // incomplete type 

template<> 
struct Static_assert_helper<true> { 
    typedef int Type; 
}; 

#define STATIC_ASSERT(cond) \ 
    typedef Static_assert_helper<(cond)>::Type JOIN(Static_assert_typedef_, __LINE__) 

它可以在很多地方使用(參見例如文檔)。

(Boost的實現較爲齊全,具有例如sizeof和中間結構,以提供更好的錯誤消息,並且是便攜式就廣泛的編譯器。)

相關問題