The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example.
The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example.
The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example.
Use type aliases like N
to make code more compact. A default template argument is maybe my personal style of saving lines of code. You will probably find this unclear, so use an explicit using N = node<T>;
declaration instead. Keeping declarations at first use like N *next
make code clearer. Don't worry about efficiency here, leave this to the optimizer.
Use type aliases like N
to make code more compact. A default template argument is maybe my personal style of saving lines of code. Keeping declarations at first use like N *next
make code clearer. Don't worry about efficiency here, leave this to the optimizer.
Use type aliases like N
to make code more compact. A default template argument is maybe my personal style of saving lines of code. You will probably find this unclear, so use an explicit using N = node<T>;
declaration instead. Keeping declarations at first use like N *next
make code clearer. Don't worry about efficiency here, leave this to the optimizer.
The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example live example.
template<typename S, typename T>
void show_node(S& s, node<T> *&list)
{
s << list->data;
list = list->next;
}
template<typename S, typename T>
S& operator<<(S& s, node<T> *list)
{
if (list)
show_node(s, list);
while (list)
{
s << ", ";
show_node(s, list);
}
return s << std::endl;s;
}
int main()
{
auto list = make_list<int>(10);
std::cout << "As built: " << list;list << std::endl;
list = reverse(list);
std::cout << "Reversed: " << list;list << std::endl;
delete_list(list);
}
The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example.
template<typename S, typename T>
void show_node(S& s, node<T> *&list)
{
s << list->data;
list = list->next;
}
template<typename S, typename T>
S& operator<<(S& s, node<T> *list)
{
if (list)
show_node(s, list);
while (list)
{
s << ", ";
show_node(s, list);
}
return s << std::endl;
}
int main()
{
auto list = make_list<int>(10);
std::cout << "As built: " << list;
list = reverse(list);
std::cout << "Reversed: " << list;
delete_list(list);
}
The code of actual reversal is fine, so like previous answers I only have a some suggestions on general style. As discussed by Corbin, raw memory management is very error prone, and you should avoid it at any cost. It is even more dangerous in the presence of exceptions; even if your code is bug-free, you can still have leaks. Without trying to change the logic too much, below are some minimal changes that will help you organize code better. Here's a live example.
template<typename S, typename T>
void show_node(S& s, node<T> *&list)
{
s << list->data;
list = list->next;
}
template<typename S, typename T>
S& operator<<(S& s, node<T> *list)
{
if (list)
show_node(s, list);
while (list)
{
s << ", ";
show_node(s, list);
}
return s;
}
int main()
{
auto list = make_list<int>(10);
std::cout << "As built: " << list << std::endl;
list = reverse(list);
std::cout << "Reversed: " << list << std::endl;
delete_list(list);
}