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