0

The following doesn't compile:

  template<typename... Args>
  void check_format(Args&&... args)
  {
      static_assert((true && std::is_fundamental<decltype(args)>::value)...);
  }
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
darune
  • 10,480
  • 2
  • 24
  • 62

2 Answers2

7

This should work:

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

Longer example on 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{}));
}
0x5453
  • 12,753
  • 1
  • 32
  • 61
4

Your attempt looks like a mix between a unary and a binary fold expression. The correct forms of the expression as either unary or binary folds are

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

The unary form works because an empty sequence is implicitly equivalent to true.

By the way, decltype(args) is always gonna be a reference type, either lvalue or rvalue. You probably want to std::remove_reference_t from those types. And you may as well use std::remove_reference_t<Args> for ease of writing.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458