best way to do variant visitation with lambdas

点点圈 提交于 2019-11-27 18:10:39
R. Martinho Fernandes

You could use variadic templates to take the lambdas, and build a variant visitor using inheritance. That would retain the compile time checks.

template <typename ReturnType, typename... Lambdas>
struct lambda_visitor : public static_visitor<ReturnType>, public Lambdas... {
    lambda_visitor(Lambdas... lambdas) : Lambdas(lambdas)... {}
};

And a little helper function to use argument type deduction (required for lambdas):

template <typename ReturnType, typename... Lambdas>
lambda_visitor<ReturnType, Lambdas...> make_lambda_visitor(Lambdas... lambdas) {
    return { lambdas... };
    // you can use the following instead if your compiler doesn't
    // support list-initialization yet
    // return lambda_visitor<ReturnType, Lambdas...>(lambdas...);
}

Now you can make visitors like this:

auto visitor = make_lambda_visitor<int>([](int) { return 42; },
                                        [](std::string) { return 17; },
                                        [](std::vector<int>) { return 23; });

Note: due to a detail of the overload resolution process that I wasn't aware of, this elegant solution causes weird ambiguity errors :(

See the follow-up question for the fix.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!