std::result_of
computes the return type of a calling expression at compile time.
As the reference says, if the call is ill-formed the instantation of std::result_of
results in a compilation error. But suppose that what we need is to check if the call is well formed, before getting the result type.
Is there any way to write a trait that checks if a calling expression is well-formed?
Something like:
template<typename F , typename... ARGS>
struct is_valid_call : public impl::is_valid_call<F,typelist<ARGS...>>
{};
namespace impl
{
struct sfinae_result{};
template<typename F , typename ARGS , typename ENABLED = sfinae_result>
struct is_valid_call;
template<typename F , typename... ARGS>
struct is_valid_call<F,typelist<ARGS...>,
decltype( std::declval<F>()(std::declval<ARGS>()...) )
> :
public std::true_type
{};
template<typename F , typename... ARGS>
struct is_valid_call<F,typelist<ARGS...>,sfinae_result> :
public std::false_type
{};
}
EDIT: Of course the solution posted doesn't work
Here's something that works:
#include <type_traits>
#include <utility>
template<typename F, typename... Args>
struct is_valid_call {
private:
template<typename FF, typename... AA>
static constexpr auto check(int) ->
decltype( std::declval<FF>()(std::declval<AA>()...), std::true_type());
template<typename FF, typename... AA>
static constexpr std::false_type check(...);
public:
static constexpr bool value = decltype(check<F, Args...>(0)){};
};
#include <cstdio>
int main()
{
printf("%d", int (is_valid_call<decltype(&puts), const char*>::value));
printf("%d", int (is_valid_call<decltype(&puts), double>::value));
}
Output: 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With