Как сложить и static_assert все параметры? - PullRequest
0 голосов
/ 10 октября 2019

Следующее не компилируется:

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

Ответы [ 2 ]

4 голосов
/ 10 октября 2019

Это должно работать:

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

Более длинный пример на Годболт: 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{}));
}
4 голосов
/ 10 октября 2019

Ваша попытка выглядит как смесь между унарным и двоичным выражением сгиба. Правильные формы выражения в виде одинарного или двоичного сгиба:

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

Унарная форма работает, потому что пустая последовательность неявно эквивалентна true.

Кстати, decltype(args) всегда будет ссылочным типом, либо lvalue, либо rvalue. Вы, вероятно, хотите std::remove_reference_t из этих типов. И вы также можете использовать std::remove_reference_t<Args> для простоты написания.

...