1

I know how to detect presence of a variable or a regular method in a C++ class. But how to do it, when the method is a template? Consider the code:

struct SomeClass
{
    template<typename Sender, typename T>
    auto& send(T& object) const
    {
        Sender::send(object);
        return object;
    };
};

How to write something like is_sendable so that is_sendable<SomeClass>::value (or any other syntax) returns true because SomeClass has method send like above ?

zupazt3
  • 966
  • 9
  • 30
  • 3
    `SomeClass::send` is a method (not a template). Do you want to detect if `SomeClass::send` is a template or do you want to detect if `SomeClass::send` can be called for some specific `Sender` and `T` ? – 463035818_is_not_an_ai Nov 24 '21 at 11:14
  • 1
    Possibly relevant .... https://stackoverflow.com/questions/39811895/is-it-possible-to-check-for-existence-of-member-templates-just-by-an-identifier – Peter Nov 24 '21 at 11:22
  • If you use `C++20` then language feature `concept` was added to deal with such tasks. If you don't then there are various complicated workarounds with SFINAE. – ALX23z Nov 24 '21 at 11:25
  • @463035818_is_not_a_number I want to detect if `SomeClass` has a method `SomeClass::send` that is callable with any `Sender` and any `T` (not a specific one) (or at least any `T`). – zupazt3 Nov 24 '21 at 13:05
  • @ALX23z Unfortunately, at this moment only up C++17. – zupazt3 Nov 24 '21 at 13:05
  • While there are some convoluted methods that can test whether some method can be called, it is much easier to simply add a field that indicates whether that class is a "sender". Declare some alias `using sender = void;` and if the type `sender` exists then presume that it is a sender. Also you can write your own type trait for this purpose. – ALX23z Nov 24 '21 at 16:20

1 Answers1

1

Ok, I acutally managed to solve it, if anyone is interested:

I needed to create a dummy class

class DummySender
{
    public:
        template<typename T>
        static void send(const T&)
        {}
};

And then I can check for the presence of the send method, by defining type traits:

template<typename T, typename = void>
struct IsSendable: std::false_type
{};

template<typename T>
struct IsSendable<T, decltype(std::declval<T>().send<DummySender>(std::cout), void())> : std::true_type
{};

To finally have IsSendable<SomeClass>::value.

zupazt3
  • 966
  • 9
  • 30