Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking correctness of function call expression

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

like image 486
Manu343726 Avatar asked Jun 15 '14 19:06

Manu343726


1 Answers

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

like image 169
jrok Avatar answered Oct 31 '22 12:10

jrok