This question already has answers here:
static_assert and class templates

(2 个回答)


2年前关闭。




鉴于以下代码( 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(您从中提取该实现的页面)为它的工作方式提供了一个 explanation:



具体来说,我们可以看到这一点。您的主要线路:

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;

};

关于c++ - std::conjunction 中的短路如何工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53357179/

10-11 21:01