Концепция проверки вариативной функции шаблона

#c #c -concepts #c 20

#c #c -концепции #c 20

Вопрос:

С C 20 и концепциями за углом я задавался вопросом, можно ли будет написать концепцию, чтобы проверить, есть ли у типа функция с определенным именем, которая принимает любое количество произвольных аргументов.

Возьмем, к примеру, следующий код (с текущим синтаксисом concept TS GCC):

 template <typename T>
concept bool Initializable = requires(T t) {
  { t.init() } ->void;
};

struct S {
  void init() {}
};

static_assert(Initializable<S>);
 

Концепция Initializable проверяет, реализует ли тип функцию void init() . Теперь давайте предположим, что существует другой тип, который также имеет функцию инициализации, но для которого требуются аргументы, например, int:

 struct T {
  void init(int) {}
};
 

Теперь в этом случае статическое утверждение завершится неудачей.

Есть ли какой-либо способ заставить инициализируемую концепцию игнорировать аргументы функции? Этот пример может показаться довольно производным, но для чего-то вроде универсального сериализатора могут быть варианты использования такой концепции.

Комментарии:

1. В чем смысл такой концепции? Как бы вы позвонили init , если не знаете, сколько / какие аргументы он принимает?

Ответ №1:

Для этого есть черта типа, std::is_member_function_pointer . Но если вы хотите, чтобы возвращаемый тип void тоже был, тогда вы можете сделать оба одновременно:

 template <typename>
struct mptr_returns_void : std::false_type {};

template <typename T, typename ...Args>
struct mptr_returns_void<void(T::*)(Args...)> : std::true_type {};


template <typename T>
concept Initializable = mptr_returns_void<decltype(amp;T::init)>::value;
 

Комментарии:

1. struct X { void init(auto) {} }; 🙂