I have is_callable trait defined like this:
#ifndef IS_CALLABLE_HPP
#define IS_CALLABLE_HPP
#include <type_traits>
namespace is_callable_detail
{
struct no {};
struct yes { no x[2]; };
template<bool CallableArgs, typename Callable, typename ReturnType, typename ...Args>
struct check_return
{
static const bool value = std::is_convertible<decltype(std::declval<Callable>()(std::declval<Args>()...)), ReturnType>::value;
};
template<typename Callable, typename ReturnType, typename ...Args>
struct check_return<false, Callable, ReturnType, Args...>
{
static const bool value = false;
};
}
template<typename Callable, typename Function>
struct is_callable;
template<typename Callable, typename ReturnType, typename ...Args>
struct is_callable<Callable, ReturnType(Args...)>
{
private:
template<typename T>
static is_callable_detail::yes check(decltype(std::declval<T>()(std::declval<Args>()...)) *);
template<typename T>
static is_callable_detail::no check(...);
static const bool value_args = sizeof(check<Callable>(nullptr)) == sizeof(is_callable_detail::yes);
static const bool value_return = is_callable_detail::check_return<value_args, Callable, ReturnType, Args...>::value;
public:
static const bool value = value_args && value_return;
};
#endif // IS_CALLABLE_HPP
My question is how to detect templated operator() which doesn't have arguments and has only return type T
template<typename T>
T operator()()
{
// ...
}
or
template<typename T, typename U>
auto operator()() -> decltype(std::declval<T>() + std::declval<U>())
{
// ...
}
I know that this situations are rare, but I wanted to ask is there any way to detect presence of templated operator() with no arguments and with one or more template arguments.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…