Search code examples
c++lambdac++17generic-programming

c++17 how to write is_pointer_pointer generic lambda?


auto is_pointer_pointer = [] ( auto arg ) -> bool {
     // implementation here
}

How would one approach implementing this generic lambda?

usage example:

int main ( int argc, char ** argv ) {
     auto dp = is_pointer_pointer(argv) ; // returns true
}

Solution

Thanks to @luk32. His solution (aka "Answer") I have taken to the wandbox, and made it a bit more resilient. Code is here.

The solution is this lambda:

  // return true if argument given is
  // pointer to pointer of it's type T
  // T ** arg
  auto is_pointer_pointer = [&] ( const auto & arg ) constexpr -> bool {
    using arg_type = std::decay_t< decltype(arg) > ;
     return std::is_pointer_v<arg_type> && 
       std::is_pointer_v< std::remove_pointer_t<arg_type> > ;
 };

For the thirsty of knowledge here is the article explaining the c++17 generic lambda issue with auto args. Hint: that is why I use std::decay above.


Solution

  • It's already possible in c++14 using decltype and type_traits facilities.

    #include <type_traits>
    #include <iostream>
    using namespace std;
    
    
    int main() {
      auto is_double_pointer = [] ( auto arg ) -> bool {
        return std::is_same<decltype(arg), double*>::value;
      };
    
      auto is_pointer_pointer = [] ( auto arg ) -> bool {
        return std::is_pointer<decltype(arg)>::value && 
               std::is_pointer< typename std::remove_pointer<decltype(arg)>::type >::value;
      };
    
    
      double d, *ptrd, **ptrptrd;
    
      std::cout << is_double_pointer(d) << '\n';
      std::cout << is_double_pointer(ptrd) << '\n';
      std::cout << is_double_pointer(ptrptrd) << '\n';
      std::cout << is_pointer_pointer(d) << '\n';
      std::cout << is_pointer_pointer(ptrd) << '\n';
      std::cout << is_pointer_pointer(ptrptrd) << '\n';
      return 0;
    }
    

    Output:

    0
    1
    0
    0
    0
    1
    

    EDIT: Also works for char** argv;