gpt4 book ai didi

c++ - 如何使用可变参数模板通过 std::visit 处理 std::variant?

转载 作者:行者123 更新时间:2023-12-03 07:00:25 25 4
gpt4 key购买 nike

我正在尝试使用命令和工厂模式来编写逻辑。基于 std::variant 里面的数据我想创建一个对象。它可能看起来像 C++ 类型的映射。
这是代码:Wandbox
我可以对所有使用的类型进行硬编码,但我想使用可变参数模板将其自动化,该怎么做?

#include <cassert>
#include <variant>
#include <type_traits>
#include <memory>
#include <iostream>


struct IFace
{
virtual void foo() = 0;
};

template<typename TKey, typename TValue>
struct Base : IFace
{
using Key = TKey;
using Value = TValue;
};

struct Int : Base<int, Int>
{
void foo() override { std::cout << "Int"; }
};

struct Double : Base<double, Double>
{
void foo() override { std::cout << "Double"; }
};

using Var = std::variant<int, double>;

template<typename ...Args>
std::shared_ptr<IFace> factory(const Var& v)
{
std::shared_ptr<IFace> p;

std::visit([&p](auto&& arg){
using TKey = std::decay_t<decltype(arg)>;
// TODO: use variadic instead of hardcoded types
if constexpr (std::is_same_v<TKey, int>)
{
using TValue = typename Base<TKey, Int>::Value;
p = std::make_shared<TValue>();
std::cout << "int ";
}
else if constexpr (std::is_same_v<TKey, double>)
{
using TValue = typename Base<TKey, Double>::Value;
p = std::make_shared<TValue>();
std::cout << "double ";
}
}, v);

return p;
}


int main()
{
const Var v = 42;
auto p = factory<Int, Double>(v);

assert(p != nullptr);
p->foo();

return 0;
}

最佳答案

这个流行的小“重载”类对于将 lambdas 传递给 std::visit 总是有用的。 :

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
然后,与其使用泛型 lambda 并试图从参数类型中推断出正确的对象类型,不如为每个 Args 生成一个重载.
template<typename ...Args>
std::shared_ptr<IFace> factory(const std::variant<typename Args::Key...>& v)
{
return std::visit(overloaded {
[](const typename Args::Key&) -> std::shared_ptr<IFace> { return std::make_shared<Args>(); }...
}, v);
}
演示: https://godbolt.org/z/nKGf3c

关于c++ - 如何使用可变参数模板通过 std::visit 处理 std::variant?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64565160/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com