Избавиться от string_view
, по крайней мере, довольно легко. У него также есть бонус в виде исключения ваших манипуляций с пространством имен std
, которые, даже если бы они были законными, все равно доставляли бы мне неудобства.
Честно говоря, ваши манипуляции с std
не являются это ужасно в качестве примера здесь, потому что вы можете легко использовать свой собственный std::pair
эквивалент и достичь того же синтаксиса.
#include <string_view>
template<typename T>
auto leaf(std::string_view s, T d) {
return std::make_pair(s, std::move(d));
}
template<typename ... T>
struct node {};
template<typename head_t, typename ... tail_t>
struct node<head_t, tail_t ...>
{
node(head_t head, tail_t... tail)
: head(std::move(head))
, tail(std::move(tail)...)
{}
head_t head;
node<tail_t ... > tail;
};
template <typename... T>
node(T... t) -> node<T...>;
int main()
{
node n{
leaf("a", 4),
leaf("b", 5),
leaf("c", node{
leaf("aaa", 12.4f)
})
};
return 0;
}
Для избавления от листа , Может быть применимо следующее: { ссылка }, но я подозреваю, что нет.
В качестве примечания, ваш класс узла может просто делегировать std::tuple<>
, который в основном делает то же самое . Это избавит вас от необходимости иметь дело с рекурсивным отслаиванием аргументов, и вам даже не понадобится руководство по выводам:
template<typename... T>
struct node
{
node(std::pair<std::string_view, T>... args)
: childs_(std::move(args)...) {}
std::tuple<std::pair<std::string_view, T>...> childs_;
};