>I was shying away from messing with the templates themselves to avoid making it string-specific...

I got that impression, but if you want to use C-style strings, you're SOL. Either use std::strings, because they overload the comparison operators, or specialize your template for C-strings. If you don't like templates, you won't like specializations. Let's say something like this:

Code:

#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
using namespace std;
template <typename T>
struct jsw_node {
T data;
jsw_node<T> *link[2];
jsw_node ( T init )
: data ( init )
{
link[0] = link[1] = 0;
}
};
template <typename T>
class jsw_tree {
jsw_node<T> *root;
public:
jsw_tree()
: root ( 0 )
{}
void insert ( T data );
void preorder ( ostream& out );
void inorder ( ostream& out );
void postorder ( ostream& out );
private:
jsw_node<T> *insert_r ( jsw_node<T> *tree, T data );
void preorder_r ( jsw_node<T> *tree, ostream& out );
void inorder_r ( jsw_node<T> *tree, ostream& out );
void postorder_r ( jsw_node<T> *tree, ostream& out );
};
template <typename T>
void jsw_tree<T>::insert ( T data )
{
root = insert_r ( root, data );
}
template <typename T>
void jsw_tree<T>::preorder ( ostream& out )
{
preorder_r ( root, out );
}
template <typename T>
void jsw_tree<T>::inorder ( ostream& out )
{
inorder_r ( root, out );
}
template <typename T>
void jsw_tree<T>::postorder ( ostream& out )
{
postorder_r ( root, out );
}
template <typename T>
jsw_node<T> *jsw_tree<T>::insert_r ( jsw_node<T> *tree, T data )
{
if ( tree == 0 )
tree = new jsw_node<T> ( data );
else {
int dir = tree->data < data;
tree->link[dir] = insert_r ( tree->link[dir], data );
}
return tree;
}
template <typename T>
void jsw_tree<T>::preorder_r ( jsw_node<T> *tree, ostream& out )
{
if ( tree != 0 ) {
cout<< tree->data <<' ';
preorder_r ( tree->link[0], out );
preorder_r ( tree->link[1], out );
}
}
template <typename T>
void jsw_tree<T>::inorder_r ( jsw_node<T> *tree, ostream& out )
{
if ( tree != 0 ) {
inorder_r ( tree->link[0], out );
cout<< tree->data <<' ';
inorder_r ( tree->link[1], out );
}
}
template <typename T>
void jsw_tree<T>::postorder_r ( jsw_node<T> *tree, ostream& out )
{
if ( tree != 0 ) {
postorder_r ( tree->link[0], out );
postorder_r ( tree->link[1], out );
cout<< tree->data <<' ';
}
}
int main()
{
string line;
cout<<"Enter a sentence: ";
if ( getline ( cin, line ) ) {
jsw_tree<string> tree;
stringstream ss ( line );
string tok;
while ( ss>> tok )
tree.insert ( tok );
tree.preorder ( cout );
cout<<'\n';
tree.inorder ( cout );
cout<<'\n';
tree.postorder ( cout );
cout<<"\n\n";
}
jsw_tree<int> tree2;
int data;
// Repeat with integers
while ( cin>> data )
tree2.insert ( data );
tree2.preorder ( cout );
cout<<'\n';
tree2.inorder ( cout );
cout<<'\n';
tree2.postorder ( cout );
cout<<'\n';
}