[prog] C++ strange linking behaviour

Kathryn Hogg kjh at flyballdogs.com
Tue Nov 9 08:22:21 EST 2004


Wolfgang Petzold said:
> On a more general level, I'm still a bit confused, though. I always
> thought, header files are where declarations and prototypes go, and the
> actual implementations go into another file. It's not a matter for me
> now (and probably won't be in the near future), but if I were selling a
> C++ template library I would have to give out the implementation code,
> too (the "templated" parts of it), for the library to be able to be
> used. Is this right?

Thats correct.  Let's day you have a template

template <class T>
class amazing_gizmo {
public:
    void rock_my_world();
};


Now when I want to use this class I would do something like

#include <amazing_gizmo.h>

int main(int, char **)
{
    amazing_gizmo<int>  not_so_amazing_afterall;

    not_so_amazing_afterall.rock_my_world();

    return int;
}

So when the compiler instiantiates "amazing_gizmo<int>" and sees the
reference to "amazing_gizmo<int>::rock_my_world()", it has to know how to
instantiate it.  In order to do that, the compiler needs to see the
definition of amazing_gizmo<T>::rock_my_world().

I have yet to see a C++ compiler where you can hid the template
definitions from instantiations.

>> template <class T>
>> struct printer
>> {
>>     const T &t;
>>     char char *sep;
>>     printer(const T &_t, const char *s = " "): t(_t), sep(s)
>>     {}
>> }
>>
>> template <class T>
>> ostream &operator << (ostream &os, const printer<T> &p>
>> {
>>      std::copy(p.t.begin(); p.t.end(),
>>                std::ostream_iterator<T>(os, p.t.sep);
>>      return os;
>> }
>>
>>
>> and then call
>>
>> std::cout << printer<int>(s) << std::endl;
>
> Wow. [Trying to reach for something to say...] Wow.
>
> Is there something like a "C++ one-liner of the month"-thing going on
> somewhere? Who said that /perl/ was the hard-to-read-language? OK, just
> kidding. But I'm impressed, really.

If you look at the code closely, you'll see that its just a wrapper around
the std::copy() method that I gave you first.  It's just a style thing but
I like the flow of not breaking up a
    cout << .... << .... << endl;
statment to print out containers.

All I did was create a little class that contains a reference to the
container and the separator char.  Then all I had to was define a '<<'
operator to print objects of this type.

This same pattern is quite useful when you want to be able to print
objects in different ways.  For example, in my software that I develop at
work, I'm dealing with objects of type message.   Normally, when I insert
a message into an iostream, I just want a quick object reference printed
out.  So thats the normal operator.  However, at other times I want a full
dump of the message contents and thats when I use a helper class like the
one above.

I haven't an iostreams book in years and back then, the only book back
then was "C++ Iostreams" by Steven Teale (aka the trout book).  It
completely predates the std::library though so I'd look for something more
recent.

-- 
Kathryn
http://womensfooty.com



More information about the Programming mailing list