Reputation: 360
I have the following code
#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;
}
which I compile with
g++ -Wall -Wextra -Wpedantic -std=gnu++17 -Wl,--wrap=malloc
My data structure is a recursive list of a std::pair
with the first element of type std::string_view
.
Now I want to get rid of std::pair
and std::string_view
in the initalization because they will always be the same type, how can I achieve this? e.g:
node n{
{"a", int{4}},
{"b", int{5}},
{"dqwd", node{
{"asdas", float{3.4}}
}
};
Upvotes: 2
Views: 99
Reputation:
Getting rid of the string_view
, at the very least, is pretty easy. It also has the bonus of eliminating your manipulation of the std
namespace, which, even if it was legal, would still be making me very uncomfortable.
To be fair, your manipulation of std
is not that horrible as an example here, because you could easily use your own std::pair
equivalent and reach the same syntax.
#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;
}
For getting rid of leaf, The following might be applicable: https://stackoverflow.com/a/51857245/4442671, but I suspect not.
As a side note, your node class could simply delegate to std::tuple<>
which does mostly the exact same thing. This would prevent you from having to deal with recursive peeling of the arguments, and you don't even need a deduction guide:
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_;
};
Upvotes: 1