Petr Skocik
Petr Skocik

Reputation: 60058

Check for the existence of a global(/namespaced) function/object declaration

C++11 allows to check, reasonably concisely, for the existence of a member: Is it possible to write a template to check for a function's existence?

Is it possible to check for the existence of a global function declaration (namespaced or not)?

Details: In my particular case, I'd like to check if my stdio.h implementation (#included) defines e.g., fprintf_unlocked (with the standard signature) and use that if it does, otherwise default to fprintf.

Upvotes: 1

Views: 992

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60058

I've made a hybrid traits generator macro that checks for either members or free standing functions.

This creates template traits classes that look whether a user supplied signature (first template arg) works with the name embedded in the traits class.

It looks for free-standing names if no second template param is supplied (Trait<Sig>::value), or for a member of the second template argument if the traits template is instantiated with two arguments (Trait<Sig,ClassToSearch>::value).

It can only search for free functions that were declared before the Traits template class was defined.

#define DEF_HAS_SIG(TraitsName, funcName) \
std::nullptr_t funcName(...); \
template<typename Sig, typename Type=void> class TraitsName { \
  typedef char yes[1];                                        \
  typedef char no [2];                                        \
  template <typename U, U> struct TypeCheck;                  \
  template <typename _1, typename _2 > static no  &chk(...);  \
  template <typename _1, typename _2> static                  \
    typename std::enable_if< std::is_same<void,_2>::value, yes&>::type chk(TypeCheck<_1, &funcName > *); \
  template <typename _1, typename _2> static yes& chk(TypeCheck<_1, &_2::funcName > *);                  \
public: static bool const value = sizeof(chk<Sig,Type>(0)) == sizeof(yes);                               \
};

Upvotes: 0

Jarod42
Jarod42

Reputation: 217235

A way to check existence of function, You may create following traits:

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)               \
    template <typename U>                                                   \
    class traitsName                                                        \
    {                                                                       \
    private:                                                                \
        template<typename T, T> struct helper;                              \
        template<typename T>                                                \
        static std::uint8_t check(helper<signature, &funcName>*);           \
        template<typename T> static std::uint16_t check(...);               \
    public:                                                                 \
        static                                                              \
        constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
    }

DEFINE_HAS_SIGNATURE(has_foo, foo, T*);
DEFINE_HAS_SIGNATURE(has_bar, bar, T*);

And then test it

has_foo<void(int)>::value

Demo

Upvotes: 3

Related Questions