Michael Galuza
Michael Galuza

Reputation: 407

How to ignore return types while using SFINAE

I have this piece of code:

template <typename T, typename R>
struct is_dereferenceable_exact
{
    typedef char yes;
    typedef struct { char dummy[2]; } no;

    template <typename U, R (U::*)() const>
    struct SFINAE;

    template <typename U>
    static yes  test(SFINAE<U, &U::operator*>*);

    template <typename U>
    static no   test(...);

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

This struct is used for checking that given type is dereferencable, and result of dereferencing has type R. I used good old approach with ellipsis and sizeof instead of void_t or detect idiom knowingly — I want to use only C++-03-features (if possible).

But I just cannot write analogous struct which determines only existence of T::operator* ignoring its type. Can you help me?

UPD I can generalize my question: if I can write some trait using return types, how I can eliminate them like in above primer?

Upvotes: 0

Views: 118

Answers (1)

W.F.
W.F.

Reputation: 13988

Maybe you could also make use of sizeof operator trick:

#include <iostream>

template <typename T>
struct is_dereferenceable_exact
{
    typedef char yes;
    typedef struct { char dummy[2]; } no;

    template <int>
    struct SFINAE;

    template <typename U>
    static yes  test(SFINAE<sizeof(&U::operator*)>*);

    template <typename U>
    static no   test(...);

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

struct A {
    int operator*() { return 0; }
};

struct B { };

int main() {
    std::cout << is_dereferenceable_exact<A>::value << std::endl;
    std::cout << is_dereferenceable_exact<B>::value << std::endl;
    return 0;
}

[live demo]

Upvotes: 5

Related Questions