Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template function with type thats missing (unused in run-time) function

Tags:

c++

templates

Say i got template function like this

template <typename T> bool func(T a)
{
  if(a.X())
    return a.Y();
  return false;
}

Now every class i use as parameter to this function has function X(), but not every class i use as parameter has function Y(). However if function a.X() returns true then i have guaranteed that given class has function Y(). Can i make this code compile somehow since i know that function Y() which compiler is whining about missing on certain types will never be called? This function is in reality really big and types used are many so making a number of specializations is impractical.

like image 964
user1316208 Avatar asked Feb 07 '26 16:02

user1316208


2 Answers

SFINAE may help, something like: (https://ideone.com/XmjQY8)

#include <type_traits>
#include <cstdint>

#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_X, T::X, bool (T::*)());
DEFINE_HAS_SIGNATURE(has_Y, T::Y, bool (T::*)());

template <typename T>
typename std::enable_if<has_X<T>::value && has_Y<T>::value, bool>::type
func(T a)
{
  if(a.X())
    return a.Y();
  return false;
}

template <typename T>
typename std::enable_if<!has_X<T>::value || !has_Y<T>::value, bool>::type
func(T /*a*/)
{
    return false;
}
like image 143
Jarod42 Avatar answered Feb 09 '26 06:02

Jarod42


Here is another version inspired by this answer which is a little shorter (and nicer in my opinion :) ).

struct Action
{
    template <typename T>
    static bool func_real(T a){return func(a, special_());}

private:

    struct general_ {};
    struct special_ : general_ {};
    template<typename> struct bool_ { typedef bool type; };

    template<typename S, typename bool_<decltype(std::declval<S>().Y())>::type = 0>
    static bool func(S a, special_) {
        cout<<"Y() exists"<<endl;
        if(a.X()){
            return a.Y();
        }
        return false;
    }

    template<typename S>
    static bool func(S a, general_) {
        cout<<"Y() does not exist"<<endl;
        return false;
    }
};

Here is a live demo.

like image 39
Scis Avatar answered Feb 09 '26 07:02

Scis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!