Dan*_*ony 2 c++ variant boost-variant
考虑以下使用的代码boost::variant(但也应该完美适用std::variant)。
#include <vector>
#include <boost/variant.hpp>
int main()
{
boost::variant<std::vector<int>, std::vector<double> > vr
= std::vector<int>(5, 5);;
// OK, no problem.
boost::apply_visitor([](auto a) { std::cout << a[0] << "\n"; }, vr);
// ERROR: return types must not differ.
//boost::apply_visitor([](auto a) { return a.begin(); }, vr);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们有一个变体,它消耗不同类型的标准向量(例如,int在double这个例子中),并且我们希望有一个访问者返回不同类型的对象(在这种情况下,迭代器到底层容器的开头) )。但是,这不会编译,因为显然std::vector<int>::iterator与std::vector<double>::iterator. 有没有一种巧妙的方法可以基本上实现这一点,可能通过额外的间接层?
您可以返回不同的变体
#include <iostream>
#include <vector>
#include <boost/variant.hpp>
int main()
{
boost::variant<std::vector<int>, std::vector<double> > vr
= std::vector<int>(5, 5);
using iter_variant = boost::variant<std::vector<int>::iterator, std::vector<double>::iterator >;
using value_variant = boost::variant<int, double>;
// OK, no problem.
boost::apply_visitor([](auto a) { std::cout << a[0] << "\n"; }, vr);
// Also OK
boost::apply_visitor([](auto a) -> iter_variant { return a.begin(); }, vr);
// Also OK
boost::apply_visitor([](auto a) -> value_variant { return a[0]; }, vr);
}
Run Code Online (Sandbox Code Playgroud)
给定一个泛型 lambda 和一个变体,您可以获得适当的返回类型。
template<typename Func, typename Variant>
struct visitor_result;
template<typename Func, typename ... Ts>
struct visitor_result<Func, boost::variant<Ts...>>
{
using type = boost::variant<decltype(std::declval<Func>()(std::declval<Ts>()))...>;
};
template<typename Func, typename Variant>
using visitor_result_t = typename visitor_result<Func, Variant>::type;
template<typename Func, typename Variant>
visitor_result_t<Func, Variant> generic_visit(Func func, Variant variant)
{
return boost::apply_visitor([&](auto a) -> visitor_result_t<Func, Variant> { return func(a); }, variant);
}
Run Code Online (Sandbox Code Playgroud)