2017-04-10 75 views
1

假設這兩個輔助結構:靜態斷言不叫

struct A { static constexpr bool Value = false; }; 
template <bool DEFERRED> struct B { static_assert(DEFERRED, "Failed"); }; 

並使用它的後續類:

class XYZ { 
public: 
    template <class X = A, class Y = B<X::Value>> int SomeFunction() {...} 

.... 
int main() { 
    XYZ xyz; 
    xyz.SomeFunction(); 
} 

我不明白爲什麼靜態斷言不叫因爲模板布爾DEFERRED應該計算爲false。但是,當我在函數體內實例化模板類型Y時,將調用靜態斷言。

有沒有辦法在不實例化模板類型Y的情況下觸發static_assert評估? (或者更簡單/更聰明的方式)

編輯:我應該提到我使用GCC 5.0

謝謝。

+0

「Static_assert」是編譯時斷言。它有效當你有本地bool_constexpr。下面添加了一些測試代碼。 – Naidu

回答

0

我想我的問題被誤解了。我的問題是,我希望編譯器在實例化類型時評估主體,而不是在聲明中使用它。無論哪種方式,我決定通過執行以下操作(使用樣板代碼)我的問題:

template <bool DEFERRED> struct B { 
    static constexpr bool Proxy = DEFERRED; 
    static_assert(Proxy , "Failed"); 
}; 
template <class X = A, bool T = B<X::Value>::Proxy> int SomeFunction() {...} 

這迫使編譯器來評估身體和觸發任何靜態斷言。

1

你可以看到一個類作爲一個對象的藍圖,你可以看到一個模板作爲一個類的藍圖。

模板只是一個模板,它不是一個類,直到您將模板實例化到一個類中,而您在變量xyz的聲明之前不會這樣做。

+0

我的印象是,當類類型被模板實例化時(編譯器會傳播並「替換」模板參數,然後執行任何浮動static_assert(s))。不是在變量實例化中使用類型時。 –

1

,因爲模板布爾遞延應該評估爲假(你的問題) ....

這是因爲在struct Aconstexpr的。

constexpr符能夠在編譯時評估bool

取出constexpr而建,你會發現其中的差別。

爲什麼你static_assert不工作:

static_assert期望一個bool_constexpr

DEFERRED只是bool,只有在我們實例化時,模板類體內的值纔是已知的。

嘗試使用以下代碼,我在struct B的內部添加了另一個bool constexpr,命名爲test。並將該變量傳遞給static_assert。現在您的static_assert工作。

//g++ 5.4.0 

#include <iostream> 

struct A { static constexpr bool Value = false; }; 
template <bool DEFERRED> struct B { 
    static constexpr bool test = false; 
    static_assert(test, "Failed"); 
}; 

class XYZ { 
public: 
    template <class X = A, class Y = B<X::Value>> int SomeFunction() 
    { 
     return 0; 
    } 
}; 


int main() 
{ 
    XYZ xyz; 
    xyz.SomeFunction(); 
} 

你會發現輸出:

source_file.cpp:8:6: error: static assertion failed: Failed 
     static_assert(test, "Failed"); 
    ^

現在struct Btest值更改爲true

它的工作原理,沒有錯誤。

還有另外一種情況,分配給DEFERRED可變test如下圖所示:

template <bool DEFERRED> struct B { 
    static constexpr bool test = DEFERRED; 
    static_assert(test, "Failed"); 
}; 

上面說的只是static_assert的作品,如果你在實例化的main(),像下面。

B<false> b;