Учитывая (пониженная) осуществление detection idiomМожем ли мы использовать идентификатор обнаружения, чтобы проверить, имеет ли класс функцию-член с определенной сигнатурой?
namespace type_traits
{
template<typename... Ts>
using void_t = void;
namespace detail
{
template<typename, template<typename...> class, typename...>
struct is_detected : std::false_type {};
template<template<class...> class Operation, typename... Arguments>
struct is_detected<void_t<Operation<Arguments...>>, Operation, Arguments...> : std::true_type {};
}
template<template<class...> class Operation, typename... Arguments>
using is_detected = detail::is_detected<void_t<>, Operation, Arguments...>;
template<template<class...> class Operation, typename... Arguments>
constexpr bool is_detected_v = detail::is_detected<void_t<>, Operation, Arguments...>::value;
}
можно легко проверить, если класс foo
содержит функцию-член bar
struct foo {
int const& bar(int&&) { return 0; }
};
template<class T>
using bar_t = decltype(std::declval<T>().bar(0));
int main()
{
static_assert(type_traits::is_detected_v<bar_t, foo>, "not detected");
return 0;
}
Однако, как вы можете видеть, мы не можем определить, что foo::bar
Тип аргумента - int&&
. Обнаружение выполнено успешно, причина 0
может быть передана до foo::bar
. Я знаю, что существует множество опций для проверки точной подписи функции (члена). Но я хотел бы знать, если можно изменить этот набор инструментов обнаружения, чтобы обнаружить, что аргумент типа foo::bar
- это точно int&&
.
[Я создал live demo этого примера.]
Это просто, если единственной неизвестной частью является тип возврата. Вы также хотите охватить несколько аргументов, в которых вы хотите точно указать некоторые из них? Как насчет cv- и ref-квалификаторов функции-члена? – dyp
Что-то вроде этого? http://coliru.stacked-crooked.com/a/38ffdc13080301c6 – dyp
@ dyp В настоящее время 'is_detected_v' будет определять, есть ли 'T' * любая * функция-член' bar', которая принимает 'int'. На первом этапе я хотел бы добавить какой-то 'is_detected_exact', который обнаруживает, что' T' имеет функцию-член 'bar', тип аргумента которого * точно *' int' или * точно * 'int &&' или * точно * 'int const &' и т. д. На втором этапе я хотел бы также проверить тип точного возврата, но я думаю, это легко, потому что 'bar_t' является именно возвращаемым типом (всякий раз, когда выражение внутри' decltype (...) 'хорошо сформирован). –
0xbadf00d