我有以下代码
#include <string_view>
#include <utility>
namespace std
{
template <typename T1, typename T2>
pair(T1 t1, T2 t2) -> pair<T1, T2>;
}
template<typename ... T>
struct node {};
template<typename head_t, typename ... tail_t>
struct node<head_t, tail_t ...>
{
node(const head_t& head, const tail_t& ... tail)
: head(head)
, tail(tail...)
{}
head_t head;
node<tail_t ... > tail;
};
template <typename... T>
node(T... t) -> node<T...>;
int main()
{
node n{
std::pair{std::string_view{"a"}, int{4}},
std::pair{std::string_view{"b"}, int{5}},
std::pair{std::string_view{"dqwd"}, node{
std::pair{std::string_view{"asdas"}, float{3.4}}
}
};
return 0;
}
我编译的
g++ -Wall -Wextra -Wpedantic -std=gnu++17 -Wl,--wrap=malloc
我的数据结构是
std::pair
的递归列表第一个元素类型为 std::string_view
.现在我想摆脱
std::pair
和 std::string_view
在初始化中,因为它们将始终是相同的类型,我该如何实现呢?例如:node n{
{"a", int{4}},
{"b", int{5}},
{"dqwd", node{
{"asdas", float{3.4}}
}
};
最佳答案
摆脱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;
}
为了摆脱叶子,以下可能适用:https://stackoverflow.com/a/51857245/4442671 ,但我怀疑不是。
附带说明一下,您的节点类可以简单地委托(delegate)给
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_;
};
关于c++ - 具有部分固定类型的递归数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61680478/