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