Nomak wrote in news:1b2zk9g53fadt$.1puyay2cubat1$.dlg@40tude.net in
comp.lang.c++:
[color=blue]
> Le 15/06/2004 à 06:28:08, Rob Williscroft <rtw@freenet.co.uk> a écrit:
>[color=green][color=darkred]
>>> [...][/color]
>>
>> Sorry, but I can't make any sense of that paragraph.
>>
>> In the absence of /export/ the compiler needs to see defenition's for
>> all templates that haven't been instantiated in another translation
>> unit. Otherwise it can't instantiate them and you get a "unresolved
>> symbol" linker error.[/color]
>
> Ok let's try again :
> - i've read several times "inline" to indicate that template
> implementation must be included in the same *translation* unit
> (included from the same .cc) as the declaration:
>
> a.hh:
>
> class A { ... };
>
> #include "a.hxx" // inline
>
> - I thought inline was in fact "implicit inlining" which is having the
> decl and impl mixed (in the class decl):
>[/color]
No templates *don't* require inline-ing (implicit or otherwise).
But (in absence of *export*) the defenition's do have to be
made available to the compiler:
// A declaration:
template < typename T > void f( T const & );
// A Defenition:
template < typename T > void f( T const & )
{
}
[color=blue]
> a.hh
>
> class A
> {
> public:
> A() { /* implicit "inline" keyword ~= macro like */ };
> ...
> };
>
> What is correct use of "inline"?[/color]
inline is for inlining it has *nothing* to do with templates.
[color=blue]
>
> And here is the working code, with several drawbacks:
>
> ===> a.hh <====
> /*
> * A decl
> */
> #ifndef A_HH
> #define A_HH
>
> // fwd decl
> #include <iosfwd> // ok for ostream, but ...[/color]
[color=blue]
> template <class _T1, class _T2> struct pair; // ... for std::pair ?[/color]
Sorry your out of luck here, the C++ Standard forbids *us* (ordinary
users / non-implementers) from making declaration's in namespace std.
Not that the above is (I assume you have an old / broken compiler).
#include <utility> /* its not *that* big :) */
[color=blue]
> template <typename T> class B; // by-hand copy => sucks
>[/color]
Yes, but that is how C++ works, we're stuck with it.
[color=blue]
>
> template <typename T>
> class A
> {
> public:
> typedef pair< T, int > pair_type;[/color]
Missing std:: again (BTW don't use "using namespace" in a header
file) it causes your code to "suck" to borrow your technical term.
[color=blue]
>
> A(const T & t);
> A(const B<T> & b);
>
> void use_pair(pair_type p);
> void dump(std::ostream & os) const;
> };
>
> #endif // ! A_HH
>
>
> ===> a.hxx <====
> /*
> * A impl
> */
> #ifndef A_HXX
> #define A_HXX
>
> // need self decl
> #include "a.hh"
>
> // need impl
> #include <ostream>
> #include "b.hxx"
>[/color]
[color=blue]
> // don't want to have std:: everywhere
> using std::ostream;[/color]
Well it isn't as bad as "using namespace" but it still
bad, though its worse for non-std names.
[color=blue]
>[/color]
[major snip][color=blue]
>
> Compilation of this is fine.
>
> But your solution is in fact having to write the forward decls by hand
> each time. Almost the same as creating .ixx for personnal template,
> and for STL template wich don't have a forward header, writing the fwd
> decls by hand is really bad (default args, hard to keep update).
>[/color]
Yes its a *known* problem (*), and if you do it yourself your programme
exhibts UB (Undefined Behaviour) IOW all bets are off, The C++ Standard
nolonger cares what you programme does.
*) People keep proposing solutions <stdfwd>, but they never seem to
get anywhere :(.
[color=blue]
> For std::pair i had to get the fwd decl for /usr/include.../stl_pair.h
> ...
>[/color]
Yup and still you got it wrong:
namespace std
{
template < typename F, typename S > struct pair;
}
#include <utility> /* it works, look ma no UB! :) */
Rob.
--
http://www.victim-prime.dsl.pipex.com/