c++ - 短路如何在 std::conjunction 中工作
问题描述
给定以下代码(https://wandbox.org/permlink/Eof3RQs49weJMWan)
#include <tuple>
#include <type_traits>
#include <utility>
template <typename T>
inline constexpr auto always_false = false;
template <typename T>
class HardError {
static_assert(always_false<T>);
};
int main() {
std::ignore = std::conjunction<std::false_type, HardError<int>>{};
}
我试图理解为什么这不会std::conjunction
像上面使用的那样出错。我知道这是为了允许短路,因此不会发生这种情况,这是设计使然。
但是,我不明白允许这种情况发生的语言规则。鉴于以下std::conjunction
实施
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
我们最终继承了这种专业化std::conditional
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };
这需要两种类类型进行实例化。那么conjunction<Bn...>
语言是如何省略的呢?
解决方案
cppreference(您从中提取该实现的页面)解释了它的工作原理:
连词是短路:如果有一个模板类型参数
Bi
,bool(Bi::value) == false
那么实例化conjunction<B1, ..., BN>::value
不需要实例化Bj::value
forj > i
。
具体来说,我们可以看到这一点。您的主要线路:
std::ignore = std::conjunction<std::false_type, HardError<int>>{};
相当于:
std::ignore.operator=(conjunction<std::integral_constant<bool, 0>, HardError<int> >{{}});
这应该会导致实例化,如下所示:
template<>
struct conjunction<std::integral_constant<bool, 0>, HardError<int> > : public std::integral_constant<bool, 0>
{
inline ~conjunction() noexcept = default;
};
推荐阅读
- sql - 从存储过程运行动态 SQL 查询以填充 GridView
- python - 不同窗口的滚动平均值(直到一个邮票超过另一个)
- python - 从列中提取值
- .net-core - 带有 Windows 身份验证的 PWA
- spring-kafka - Spring-kafka 支持只执行一次 SeekToTimestamp
- spring-boot - Spring kotlin - 如何将内部类注入公共类
- python - 忽略 Python CSV 读取上的特定分隔符场景
- pandas - 如何在我的 vscode 项目中修复熊猫代码的错误 pylance 警告?
- firebase - Flutter Web:初始化firebase应用程序时需要刷新
- python - Lambda 实现事务