我有一个二进制格式,我正在为其编写编码器和解码器。几乎所有二进制类型都直接映射到基元,除了两种容器类型(列表和映射类型)之外,它们可以包含格式中的任何其他类型(包括它们本身)。
这些感觉就像他们只是想成为一个 typedefstd::variant
typedef std::variant<std::vector<char>, std::vector<int>, ...> ListType
但是因为我需要能够包含 ListType 本身的向量,所以我最终这样做了
struct ListType {
std::variant<std::vector<char>, std::vector<int>, ..., std::vector<ListType>> value;
}
这给使用该类型增加了一些摩擦。这些变量实际上没有其他状态可以证明封装它们是合理的。
打出来后我意识到我在问“你能转发声明一个模板吗?”这似乎是一个愚蠢的问题。不过,有人对此有更好的策略吗?
template<class...Ts>
struct self_variant;
template<class...Ts>
using self_variant_base =
std::variant<
std::vector<Ts>...,
std::vector<self_variant<Ts...>>
>;
template<class...Ts>
struct self_variant:
self_variant_base<Ts...>
{
using self_variant_base<Ts...>::self_variant_base;
self_variant_base<Ts...> const& base() const { return *this; }
self_variant_base<Ts...>& base() { return *this; }
};
template<class T>
void print( T const& t ) {
std::cout << t << ",";
}
template<class T>
void print( std::vector<T> const& v ) {
std::cout << "[";
for (auto const& e:v) {
print(e);
}
std::cout << "]\n";
}
template<class...Ts>
void print( self_variant<Ts...> const& sv ) {
std::visit( [](auto& e){
print(e);
}, sv.base());
}
int main() {
self_variant<int, char> bob = std::vector<int>{1,2,3};
self_variant<int, char> alice = std::vector<self_variant<int, char>>{ bob, bob, bob };
print(alice);
}
所以,需要.base()
是因为std::visit
措辞有点错误。我相信这将在未来的标准修订中得到解决。
无论如何,这会稍微减少摩擦。
实例,3 递归深度实例 https://godbolt.org/z/4z8oh8nxK.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)