First, if you want to output chars (and all of the chars), you'll need to use ostreambuf_iterator<char>, and not ostream_iterator<string>. And ostreambuf_iterator<char> expresses better what you want than ostream_iterator<char>; you're outputting chars directly, not formatting anything. (ostream_iterator uses the << operator, which formats.)
Second, be aware that there is not always a one to one translation of lower to upper (e.g. 'ß' maps to the two character sequence "SS" in upper case), so std::transform can't really be used to do the job correctly. (And of course, it doesn't handle multibyte encodings like UTF-8 correctly.) For all but the simplest uses, you need something more complicated. But even for the simplest cases:
std::toupper is overloaded: one of the overloads is a template, which takes two arguments, and the other is a function which takes a single int; neither will work directly here, and the fact that transform is also a template means that overload resolution and template type deduction won't work even if they did. So basically, you have to add something. It's possible to use the 2 argument template function if you add enough qualifiers and use boost::bind or something similar to bind the second argument, but it's almost as much text as writing a simple toupper functional argument your self. And you can't use the single argument form (which can be unambiguously accessed if you include <ctype.h> and use ::toupper) because it has undefined behavior if you use a char as the argument when you call it: you have to convert the char to unsigned char first (unless, of course, plain char is unsigned in the implementation you are using—and in all implementations to which your code will ever be ported).