1

I would like to specialize a structure when the passed type has an operator() (a functor or a lambda function). For the moment, I have this code:

#include <iostream>
#include <type_traits>

template <class...>
struct mystruct: std::false_type {};

template <class C> 
struct mystruct<C, decltype(&C::operator())>: std::true_type {};

int main() {
    int n = 42;
    auto lambda = [&n](int i){return i + n;};

    // Should return false: OK
    std::cout<<mystruct<decltype(x)>::value<<std::endl;

    // Should return true: problem
    std::cout<<mystruct<decltype(lambda)>::value<<std::endl; 

    return 0;
}

How to make it work?

Bonus question: how to make it work even when the operator() is protected or private?

Vincent
  • 57,703
  • 61
  • 205
  • 388

1 Answers1

2

This would be an appropriate use of the void_t technique:

template <class, class = std::void_t<>>
struct mystruct: std::false_type {};

template <class C> 
struct mystruct<C, std::void_t<decltype(&C::operator())>>: std::true_type {};

Although void_t is only in the library since C++17, it is easy to add to your own utility library.

For the bonus question, see Detect existence of private member.

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366