Saturday, November 5, 2022

[FIXED] How to write a lambda function that can only take in int or float pointers?

Issue

I need to create a lambda function that can take in either a int * or a float *, e.g., something like

auto func = [](void* ptr) {
  // do some assignments with the pointer
}

Currently, I am using the void * approach, but I'm wondering what are some other approaches to accomplish what I want?

I don't have access to C++17 features in my codebase so will have to stick to C++14 or lower semantics.


Solution

C++14 has generic lambdas, meaning you can use SFINAE on them, e.g. in their trailing return types:

#include <type_traits>

template <typename T> struct valid_ptr_type : std::false_type {};
template <> struct valid_ptr_type<int *>    : std::true_type {};
template <> struct valid_ptr_type<float *>  : std::true_type {};

template <typename T> constexpr bool valid_ptr_type_v{valid_ptr_type<T>::value};

int main() {
  // only allow ptr args that fulfills
  // the valid_ptr_type_v<decltype(ptr)> trait
  auto func = [](auto *ptr) ->
      std::enable_if_t<valid_ptr_type_v<decltype(ptr)>> {
          // do stuff with ptr
      };  // note: void return type (std::enable_if default)

  int a{};
  float b{};
  char c{};
  func(&a);
  func(&b);
  // func(&c);  // error
}

What this does behind the hood is to constrain the deduced single template parameter of the template function call operator of the lambda's closure type.

// ~ish
struct AnonClosureTypeOfGenericLambda {
    template <typename T, 
              typename = std::enable_if_t<valid_ptr_type_v<decltype(T*)>>>
    void operator()(T* ptr) const { /* ... */ }
};


Answered By - dfrib
Answer Checked By - Mary Flores (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.