这实际上非常有用,但这取决于你想对整个事情有多直接。考虑以下代码:
#include <boost/variant.hpp>
#include <iostream>
#include <string>
#include <unordered_map>
template <class R, class T, class ... Ts>
struct Inheritor : public T, Inheritor<R, Ts...>
{
using T::operator();
using Inheritor<R, Ts...>::operator();
Inheritor(T t, Ts ... ts) : T(t), Inheritor<R, Ts...>(ts...) {}
};
template <class R, class T>
struct Inheritor<R, T> : public boost::static_visitor<R>, T
{
using T::operator();
Inheritor(T t) : T(t) {}
};
template <class R, class V, class ... T>
auto apply_visitor_inline(V& v, T ... t)
{
Inheritor<R, T...> i(t...);
return boost::apply_visitor(i, v);
}
int main()
{
boost::variant< int, std::string > u("hello world");
boost::variant< int, std::string > u2(5);
auto result = apply_visitor_inline<int64_t>(u, [] (int i) { return i;}, [] (const std::string& s) { return s.size();});
auto result2 = apply_visitor_inline<int64_t>(u2, [] (int i) { return i;}, [] (const std::string& s) { return s.size();});
std::cout << result;
std::cout << result2;
}
您问题中的 sn-p 在任何地方都没有以确切的形式显示。但是您可以看到,在 apply_visitor_inline 中推断出 lambda 的类型。然后实例化一个继承自所有这些 lambda 的类。目的?我们可以将多个 lambdas 组合成一个,以达到apply_visitor 之类的目的。此函数期望接收定义多个operator() 的单个函数对象,并根据重载区分它们。但有时定义一个对我们必须涵盖的每种类型进行操作的 lambda 会更方便。在这种情况下,从 lambdas 继承提供了一种组合机制。
我从这里得到了内联访问者的想法:https://github.com/exclipy/inline_variant_visitor,虽然我没有看那里的实现,所以这个实现是我自己的(但我猜它非常相似)。
编辑:最初发布的代码仅由于 clang 中的错误而起作用。根据这个问题(Overloaded lambdas in C++ and differences between clang and gcc),在基类中查找多个operator() 是模棱两可的,而且我最初发布的代码确实没有在 gcc 中编译。新代码在两者中编译并且应该是合规的。遗憾的是,似乎无法使用可变参数 using 语句,因此必须使用递归。