Я пытаюсь проверить, совместим ли функтор с заданным набором типов параметров и заданным возвратом type (то есть заданные типы параметров могут быть неявно преобразованы в фактические типы параметров и наоборот для возвращаемого типа). В настоящее время я использую для этого следующий код:
template<typename T, typename R, template<typename U, typename V> class Comparer>
struct check_type
{ enum {value = Comparer<T, R>::value}; };
template<typename T, typename Return, typename... Args>
struct is_functor_compatible
{
struct base: public T
{
using T::operator();
std::false_type operator()(...)const;
};
enum {value = check_type<decltype(std::declval<base>()(std::declval<Args>()...)), Return, std::is_convertible>::value};
};
check_type
Это работает довольно хорошо в большинстве случаев, однако он не компилируется, когда я тестирую функторы без параметров, такие как struct foo {int operator () () const;};
, потому что в В этом случае два operator ()
базы кажутся неоднозначными, что приводит к примерно следующему:
error: call of '(is_functor_compatible<foo, void>::base) ()' is ambiguous
note: candidates are:
note: std::false_type is_functor_compatible<T, Return, Args>::base::operator()(...) const [with T = foo, Return = void, Args = {}, std::false_type = std::integral_constant<bool, false>]
note: int foo::operator()() const
Очевидно, мне нужно другое арендуйте способ проверить это для функторов без параметров. Я попытался сделать частичную специализацию is_functor_compatible
для пустого пакета параметров, где я проверяю, является ли тип & T :: operator ()
функцией-членом без параметров, которая работает более или менее. Однако этот подход явно не работает, когда тестируемый функтор имеет несколько operator ()
.
Поэтому мой вопрос в том, есть ли лучший способ проверить существование безпараметрического оператора ()
и как это сделать.