如何折叠和static_assert所有参数?

时间:2019-10-10 13:26:34

标签: c++ c++17 variadic-templates static-assert fold-expression

以下内容无法编译:

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

2 个答案:

答案 0 :(得分:4)

您的尝试似乎是一元和二进制折叠表达式之间的混合。一元或二元折叠的正确表达形式是

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>来简化编写。

答案 1 :(得分:4)

这应该有效:

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{}));
}