我using V = std::variant<A, B, C>的原型有一些变体和功能V parse(const json&)。函数应尝试解析所有类型(例如A,,B然后C),直到首次成功为止(并且应隐式执行,因为及时会有很多类型)。
如何实现这种东西?
我们可能会std::variant_size以某种方式使用。
这是我需要的东西。
我的解决方案是显式列出所有类型的解析器。
V parse(const json& i_j)
{
using Parser = std::function<MaybeV(const json&)>;
static const auto ps = std::vector<Parser>{
[](const auto& j)->MaybeV{return j.get<std::optional<A>>;},
[](const auto& j)->MaybeV{return j.get<std::optional<B>>;},
[](const auto& j)->MaybeV{return j.get<std::optional<C>>;}
};
for (const auto& p : ps)
if (auto opt_result = p(i_j))
return std::move(*opt_result);
throw ParseError("Can't parse");
}
Run Code Online (Sandbox Code Playgroud)
但是,它肯定可以简化,因为lambda的类型仅不同,而我真正需要的是迭代的类型std::variant。
我的原型有一些变体using V = std::variant<A, B, C>和功能。foovoid foo(const T&)
并希望我的函数在传递的类型之一时foo进行std::enable_if编辑V(而无需明确指示它们)。
我V将及时得到越来越多的类型,因此
template<class T,
typename std::enable_if<
std::is_same_v<T, A> || std::is_same_v<T, B> || std::is_same_v<T, C>,
int>::type = 0>
void foo(const T&);
Run Code Online (Sandbox Code Playgroud)
是不能接受的。
这是一个增强的解决方案。
是否可以实现的逻辑std::variant?
理想情况下,类型特征应看起来像is_one_of_variants_types<V, T>。
我想实现以下目标:
#include <iostream>
#include <fstream>
#include <string>
void write(std::ofstream& o)
{
o << "Some text..." << std::endl;
}
int main(const int argc, const char** argv)
{
if (argc == 2){
auto outputStream = std::ofstream(argv[1]);
write(outputStream);
}
else{
auto outputStream = std::ofstream(std::cout);
write();
}
}
Run Code Online (Sandbox Code Playgroud)
该代码无法编译,因为std::ofstream无法从构建std::cout。
一个可行的解决方案是rdbuf()在上下文中使用pointer_to_ofstream->basic_ios<char>::rdbuf(std::cout.rdbuf())(如本条目中所述)。
有更好的解决方案吗?