如何折叠和static_assert所有参数?

How to fold and static_assert all parameters?

本文关键字:assert 参数 static 何折叠 折叠      更新时间:2023-10-16

以下内容无法编译:

template<typename... Args>
void check_format(Args&&... args)
{
static_assert((true && std::is_fundamental<decltype(args)>::value)...);
}

这应该有效:

static_assert((std::is_fundamental_v<Args> && ...));

关于 godbolt 的更长示例:https://gcc.godbolt.org/z/9yNf15

#include <type_traits>
template<typename... Args>
constexpr bool check_format(Args&&... args)
{
return (std::is_fundamental_v<Args> && ...);
}
int main() {
static_assert(check_format(1, 2, 3));
static_assert(check_format(nullptr));
static_assert(!check_format("a"));
static_assert(check_format());
struct Foo {};
static_assert(!check_format(Foo{}));
}

您的尝试看起来像是一元和二进制折叠表达式之间的混合。表达式的正确形式为一元或二进制折叠是

static_assert((... && std::is_fundamental<decltype(args)>::value));         // unary
static_assert((true && ... && std::is_fundamental<decltype(args)>::value)); // binary

一元形式之所以有效,是因为空序列隐式等价于true

顺便说一下,decltype(args)总是引用类型,左值或右值。您可能希望从这些类型中std::remove_reference_t。您也可以使用std::remove_reference_t<Args>来简化写作。