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.
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;
}
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.
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