2

我具有n任何布爾OR運行時功能any_run冗餘實例

#include <assert.h> 

bool any_run() { return false; } 

template <typename... B> 
bool any_run(bool a, B... b) 
{ 
    assert(a); 
    return a || any_run(b...); 
} 

以及編譯時類似物any_comp

#include <type_traits> 

template <bool E> 
using expr = std::integral_constant <bool, E>; 

using _true = expr <true>; 
using _false = expr <false>; 

template <typename... A> 
struct any_comp : public _false { }; 

template <typename A, typename... B> 
struct any_comp <A, B...> : public expr <A() || any_comp <B...>()> 
{ 
    static_assert(A(), ""); 
}; 

兩者均含有的斷言(分別爲運行時或編譯時)確保第一個參數爲真。

現在給下面的輸入

int main() 
{ 
    any_run (true, false, false); 
    any_comp <_true, _false, _false>(); 
} 

運行時斷言永遠不會失敗,但編譯時人做。這意味着,any_run(false, false)不會被調用,但是any_comp <_false, _false>不會被實例化,儘管布爾常數表達式

A() || any_comp <B...>() 

可以進行評估,以true如果A() == true而沒有實例any_comp <B...>的事實。

我的問題是本實驗及其結論是否有效,以及該標準對此有何說法。

這很重要,因爲如果結論是有效的,我必須更仔細地(更專業化地)重新實現幾個編譯時函數,以加快編譯速度,儘管我通常更喜歡儘可能簡單。

回答

3

短路僅適用於||的運行時級別。在編譯時,你需要其他的東西,如:

#include <type_traits> 

template <typename T, typename U> 
struct integral_or : U { }; 

template <typename U> 
struct integral_or <std::true_type, U> : std::true_type { }; 

template <typename... A> 
struct any_comp : std::false_type { }; 

template <typename A, typename... B> 
struct any_comp <A, B...> : integral_or <A, any_comp <B...>> 
{ 
    static_assert(A(), ""); 
}; 

int main() 
{ 
    any_comp <std::true_type, std::false_type, std::false_type>(); 
} 
+0

正確...我們(幾乎)回到C++ 03 ...我很高興拋棄所有這些功能,如'當發生更復雜的表達式時,這使得所有內容都變得難以理解。謝謝! – iavr

+0

您也可以重載布爾運算符來實現表達式模板,並提供更清晰的語法(例如'decltype(a()|| b()&& c())',例如[this](https://github.com /Manu343726/Turbo/blob/master/expressions.hpp) – Manu343726