Lambda function argument + deduction enhancement

I built this template function for a double loop for a loop that needs to do a lot and was done with a macro:

template <typename TYPE_OF_ENTITY, typename LAMBDA_FUNC>
void foreach_t(list faces, LAMBDA_FUNC func)
{
    for(...)
        for(...)
            func(pEnt)
}

      

This worked very well and could be called:

foreach_t<FACE>(faces,[&](FACE* pFace){...});

      

Then I wanted to say that your lambda should have TYPE_OF_ENTITY * as an argument. For this I needed the statefull and stateless function.

template <typename TYPE_OF_ENTITY, typename LAMBDA_RETURN_TYPE>
using functionPtr = LAMBDA_RETURN_TYPE(*)(TYPE_OF_ENTITY*);

template <typename TYPE_OF_ENTITY, typename LAMBDA_RETURN_TYPE>
void foreach_t(list faces, functionPtr<TYPE_OF_ENTITY, LAMBDA_RETURN_TYPE> func)
{
    for(...)
        for(...)
            func(pEnt)
}

template <typename TYPE_OF_ENTITY, typename LAMBDA_RETURN_TYPE>
void foreach_t(list faces, std::function<LAMBDA_RETURN_TYPE(TYPE_OF_ENTITY*)> func)
{
    for(...)
        for(...)
            func(pEnt)
}

      

They work the way I want, only now I have to specify 2 template arguments as they can no longer be output:

foreach_t<FACE, void>(faces,[&](FACE* pFace){...});

      

Is there a way to improve this output so I only need to pass the arguments to the function?

If possible, it should be supported by Visual Studio 2013 compatible compiler v2.1

+3


source to share


2 answers


If all you have to do is check that the lambda takes a type value as TYPE_OF_ENTITY*

a parameter, you really don't need to split the function into two separate overloads (for statefull and stateless lambda). You can just check if it can be called with a parameter like this:



#include <type_traits> // for std::declval

template <typename TYPE_OF_ENTITY, typename LAMBDA_FUNC>
auto foreach_t(list faces, LAMBDA_FUNC func) -> decltype(func(std::declval<TYPE_OF_ENTITY*>()), void())
{
    for(...)
        for(...)
            func(pEnt)
}

      

+3


source


If you want to specify the return type of the closure at the point of the function call, then it static_assert

might be helpful:



#include <utility>
#include <vector>

struct Dog {};

struct list {};

template <
typename LAMBDA_RETURN_TYPE,
  typename TYPE_OF_ENTITY, 
class F
>
void foreach_t(const std::vector<TYPE_OF_ENTITY*>& faces, F func)
{
  using ret_type = decltype(func(std::declval<TYPE_OF_ENTITY*>()));
  using same_type = typename std::is_same<LAMBDA_RETURN_TYPE, ret_type>::type;
  constexpr auto ok = same_type::value;
  static_assert(ok, "");
  for(auto pdog : faces)
    func(pdog);
}

int main()
{
  auto mydog = [](Dog* pdog) -> bool // change to int and this compiles
  { return false; };

  std::vector<Dog*> dogs;
  foreach_t<int>(dogs, mydog);  

}

      

+3


source







All Articles