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
source to share
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)
}
source to share
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);
}
source to share