From: Daniel Krügler on
On 4 Jun., 07:41, Jun <junh...(a)gmail.com> wrote:
> Just a stupid problem, since i need to separate codes in header and
> source files (for cross reference),
> I found it's really difficult to work with templates in separated
> source file.
>
> For example:
>
> // MyClass.h
>
> template <class T>
> struct MyClass{
>
> Template <typename InputIterator>
> T getMyBaby(InputIterator first, InputIterator last){}

Two observations: Fix the typo ("Template") and be aware
that above is already a member *definition*, because
of the pair of braces. If you want to define the member outside of
the class, you need to change this first to a non-defining
declaration like so:

template <typename InputIterator>
T getMyBaby(InputIterator first, InputIterator last);

> };
>
> How can I implement getMyBaby in separated cpp file?
>
> since,
>
> template<typename InputIterator> T template <class T>
> MyClass<T>::getMyBaby( .... )
>
> just doesn't work ...

"Doesn't work" has very different flavors, so I strongly recommend
to describe the precise problem you have (aka: compiler diagnostics).

Also note, that there are more than one problem with your attempt:

1) Your out-of-class definition is defective, because it does
not follow the required syntax. The correct syntax would be:

template <class T> template<typename InputIterator>
T MyClass<T>::getMyBaby(InputIterator first, InputIterator last){
return [..]
}

where [..] should correspond to your actual return code. Note the
wrong position of the return type and the wrong ordering of
your template arguments.

2) The fixed syntax shown in (1) should work, but it may still not
realize what you are attempting to do: Your requirement was:

"i need to separate codes in header and source files (for cross
reference)"

I'm not sure what precisely you mean with the part "(for cross
reference)",
but as written this implementation will only allow for instantiating
the
member definition *within* the translation unit where the definition
has been written and you cannot realize that code attempting
to instantiate this definition within a *different* translation unit
will
succeed, because C++ (without template export) does not support
this. You either are required to make the out-of-class definition
available within the other translation units (a typical way to
realize
that is to move the out-of-class definition in a header) or you need
to provide an explicit instantiation of the corresponding template
argument type combination within the separate cpp file following the
definition, e.g.:

template double MyClass<double>::getMyBaby(int* first, int* last);

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: SG on
On 4 Jun., 07:41, Jun wrote:
>
> I found it's really difficult to work with templates in
> separated source file.

There are special rules for templates. You have to keep in mind that
only in certain situations a compiler would actually create a specific
function from a function template. Obviously, it has to know the
definition to do so. So, hiding the definition in some .cpp file makes
it difficult to use a specific instantiation of the function template
in another .cpp file. In theory, something like this requires the use
of the "export" keyword. But almost no compiler supports it. So,
you're left with defining function templates in header files and
including those into all the translation units that need the
definitions. The one-definition-rule actually allows this. Just like
in the case with inline function definitions, multiple function
template definitions (in different TUs) are supported as long as
they're equivalent. The linker won't complain. It'll simply remove
duplicates.

> For example:
>
> // MyClass.h
>
> template <class T>
> struct MyClass{
> template <typename InputIterator>
> T getMyBaby(InputIterator first, InputIterator last){}
> };
>
> How can I implement getMyBaby in separated cpp file?

You can't. But you can remove the definition and create a special file
for it. It just shouldn't have a cpp extension as it really is not
supposed to be compiled in isolation. Here's one approach:

--------8<--------

// MyClass.h

template <class T>
struct MyClass {
template <typename InputIterator>
T getMyBaby(InputIterator first, InputIterator last);
};

#include "MyClass.tpp"

--------8<--------

// MyClass.tpp

template <class T>
template <typename Iterator>
T MyClass<T>::getMyBaby(Iterator first, Iterator last)
{
.
}

--------8<--------

But the only thing it buys you is a more compact header file with
function template definitions isolated in another file. In terms of
dependencies (some translation units still depend on this .tpp file)
you really can't do any better.

To be honest, I don't even know how the "export-solution" looks like.
I just havn't had the chance to test a compiler that actually supports
the export keyword. If I recall correctly, the "exported templates"
feature has been completely removed from the latest draft of the
upcoming C++ standard. It only refers to "export" as a reserved
keyword that may be used in the future. So, I guess that means
"exported templates" are history.


Cheers,
SG


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]