So while refactoring my code that uses functors into lambdas, I came across a specific function-pointer table used for sorting that I'm struggling to get right. Thats the current code
// some functors:
struct FrontToBackSorter
{
inline bool operator()(const SortData& left, const SortData& right) const
{
return left.z > right.z;
}
};
struct BackToFrontSorter
{
inline bool operator()(const SortData& left, const SortData& right) const
{
return left.z < right.z;
}
};
struct TextureSorter
{
inline bool operator()(const SortData& left, const SortData& right) const
{
return left.pTexture < right.pTexture;
}
};
// the table, sort-function etc...
template<typename Sorter>
void sortFunction(SortingVector& vSortData)
{
std::stable_sort(vSortData.begin(), vSortData.end(), Sorter());
}
using SortFunction = void (*)(SortingVector&);
constexpr SortFunction sortFunctions[] =
{
&sortFunction<BackToFrontSorter>, &sortFunction<FrontToBackSorter>, &sortFunction<TextureSorter>
...
};
Now as I said I would like to replace those functors with lambdas, but since I can't store the lambda itself but another somehow generate the code for "sortFunction" with the lambda instead of Sorter, I really don't know how to pull this off (storing the sort-function & calling std::stable_sort with the adress is not an option since it absolutely has to be inlined). Thats the closest I got so far:
template<typename Sorter>
void sortFunction(SortingVector& vSortData)
{
std::stable_sort(vSortData.begin(), vSortData.end(), Sorter()); // error: lambda default-ctor deleted
}
constexpr auto generateSortFunctions(void)
{
constexpr auto frontToBack = [](const SortData& left, const SortData& right)
{
return left.z > right.z;
};
constexpr auto backToFront = [](const SortData& left, const SortData& right)
{
return left.z < right.z;
};
constexpr auto texture = [](const SortData& left, const SortData& right)
{
return left.pTexture < right.pTexture;
};
using SortFunction = void(*)(SortingVector& vSortData);
constexpr std::array<SortFunction, 3> vFunctions =
{
&sortFunction<decltype(backToFront)>,
&sortFunction<decltype(frontToBack)>,
&sortFunction<decltype(texture)>,
};
return vFunctions;
}
Unfortunately this doesn't work since you cannot instantiate a lambda directly.
So, any ideas how this could work? Is this even possible (without lots of redundant work like writing a second lambda that includes the sort for every instantiation? std::function (which I suppose could work) & type-erasure should also be avoided if possible, since this is performance-critic code.
Thanks!
↧