Search code examples
templatesc++11template-meta-programmingtype-traitsenable-if

Enable if to check whether the passed type is a compliant function?


Consider the following code:

template <class Function, class = typename std::enable_if</*SOMETHING*/>::type>
apply(Function&& f);

which execute the provided function.

To use SFINAE, I would like to check whether the function satisfy the following conditions:

  • it takes one parameter convertible to const unsigned int
  • it returns something convertible to a std::string

What do I have to write instead of /*SOMETHING*/ ?


Solution

  • You haven't specified a return value for apply, I'll choose int:

    #include <string>
    #include <type_traits>
    
    template <class Function,
      class = typename std::enable_if<
        std::is_convertible<
          decltype(std::declval<Function>()(std::declval<const unsigned int>())),std::string>::value>::type>
    int apply(Function&& f);
    

    Breaking it down: this ensures that a Function:

    std::declval<Function>()
    

    called with a const unsigned int parameter:

    std::declval<Function()(std::declval<const unsigned int>())
    

    has a return type:

    decltype(std::declval<Function()(std::declval<const unsigned int>()))
    

    that is convertible to std::string:

    std::is_convertible<decltype(std::declval<Function()(std::declval<const unsigned int>())), std::string>
    

    whew.