Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C++ Programming

operator<< for standard output and templates


Hi everyone,

I was unable to find out why my code is not compiling. I have a
template class and I'm trying to write the operator<< for standard
output. Does anyone know why this is not right? The code is as
follows...

// main class:
template <
class Individual,
class SelectionPolicy,
template <class> class CrossOverPolicy = OnePointX,
class StoragePolicy = VectorPolicy<Individual>


class Population : public SelectionPolicy, public
CrossOverPolicy<Individual> {

 // member variables and functions

 // friend declaration for standard output
  template <class I,class Se,template <class> class C,class St>
  friend ostream& operator<<(ostream& os, Population<I,Se,C,St>& pop);

};

// operator<< definition
template <class Individual,class SelectionPolicy,template <class>
class CrossOverPolicy,class StoragePolicy>
ostream& operator<<(ostream& os,
Population<Individual,SelectionPolicy,CrossOverPolicy,StoragePolicy>&
pop) {

    os<<"pop"<<endl;
    return os;

}

// main function
int main(){

    typedef Population<ind, t > pop;
    pop ccc(10);
    cout<<ccc<<endl;
    return 0;

}

The compiler error message is:

main.cxx:104: error: ambiguous overload for 'operator<<' in 'std::cout
<< ccc'
gaPopulation.h:411: note: candidates are: std::ostream&
operator<<(std::ostream&, Population<I, Se, C, St>&) [with I =
Individual<Chromosome<Objective<1u, Optimizator<minimize> >,
BitSetPolicy, 2>, ClockMutator>, Se = TournamentSelector<2>, C =
OnePointX, St = VectorPolicy<Individual<Chromosome<Objective<1u,
Optimizator<minimize> >, BitSetPolicy, 2>, ClockMutator> >, Individual
= Individual<Chromosome<Objective<1u, Optimizator<minimize> >,
BitSetPolicy, 2>, ClockMutator>, SelectionPolicy =
TournamentSelector<2>, CrossOverPolicy = OnePointX, StoragePolicy =
VectorPolicy<Individual<Chromosome<Objective<1u, Optimizator<minimize>

>, BitSetPolicy, 2>, ClockMutator> >]

gaPopulation.h:441: note:                 std::ostream&
operator<<(std::ostream&, Population<Individual, SelectionPolicy,
CrossOverPolicy, StoragePolicy>&) [with Individual =
Individual<Chromosome<Objective<1u, Optimizator<minimize> >,
BitSetPolicy, 2>, ClockMutator>, SelectionPolicy =
TournamentSelector<2>, CrossOverPolicy = OnePointX, StoragePolicy =
VectorPolicy<Individual<Chromosome<Objective<1u, Optimizator<minimize>
>, BitSetPolicy, 2>, ClockMutator> >]

make[2]: *** [main.o] Error 1

Thank you,

a^2

On Jun 4, 12:32 am, aaragon <alejandro.ara@gmail.com> wrote:

> I was unable to find out why my code is not compiling. I have a
> template class and I'm trying to write the operator<< for standard
> output. Does anyone know why this is not right? The code is as
> follows...

Classical problem...

> // main class:
> template <
> class Individual,
> class SelectionPolicy,
> template <class> class CrossOverPolicy = OnePointX,
> class StoragePolicy = VectorPolicy<Individual>
> class Population : public SelectionPolicy, public
> CrossOverPolicy<Individual> {

>  // member variables and functions
>  // friend declaration for standard output
>   template <class I,class Se,template <class> class C,class St>
>   friend ostream& operator<<(ostream& os, Population<I,Se,C,St>& pop);

Here you declare for each instantiation of the template a
non-template function, which takes the specific instance.  This
is the function that the compiler will try to call when you use
<< on the object.

> };
> // operator<< definition
> template <class Individual,class SelectionPolicy,template <class>
> class CrossOverPolicy,class StoragePolicy>
> ostream& operator<<(ostream& os,
> Population<Individual,SelectionPolicy,CrossOverPolicy,StoragePolicy>&
> pop) {
>     os<<"pop"<<endl;
>     return os;
> }

And here you've just defined a function template.  You now have
two possible functions which can be called with <<.

> // main function
> int main(){

>     typedef Population<ind, t > pop;
>     pop ccc(10);
>     cout<<ccc<<endl;

The compiler sees the two functions, the template, and the
non-template.  Both are equal matches, so the non-template is
chosen.  And you don't have a definition of it, so the linker
complains.

I wouldn't have expected ambiguous.  All other things being
equal, the compiler should prefer the non-template over the
template.  Of course, that would just give you a linker error,
so you wouldn't get much further.

There are two simple solutions: provide the definition for the
operator<< in the friend declaration, or provide a non-friend
template function outside the class.  (A non-friend or the
operator<< definition in the class can, of course, call other
member functions, e.g. you provide a member
print(std::ostream&), which is called by the template function
operator<<.)

--
James Kanze (Gabi Software)            email: james.ka@gmail.com
Conseils en informatique oriente objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34

On Jun 3, 6:38 pm, James Kanze <james.ka@gmail.com> wrote:

Thank you James for your answer, I tried both ways and they work.
Something that I don't really understand is why the friend declaration
within the class is a non-template declaration? If you put the
template <template parameters> before the keyword 'friend', aren't you
declaring this as a template function?
Once again, thanks for the answer.
On Jun 4, 6:34 am, aaragon <alejandro.ara@gmail.com> wrote:

    [...]

> > There are two simple solutions: provide the definition for the
> > operator<< in the friend declaration, or provide a non-friend
> > template function outside the class.  (A non-friend or the
> > operator<< definition in the class can, of course, call other
> > member functions, e.g. you provide a member
> > print(std::ostream&), which is called by the template function
> > operator<<.)
> Thank you James for your answer, I tried both ways and they work.
> Something that I don't really understand is why the friend declaration
> within the class is a non-template declaration? If you put the
> template <template parameters> before the keyword 'friend', aren't you
> declaring this as a template function?
> Once again, thanks for the answer.

I missed them.  Originally, templates couldn't be friends; this
possibility was added to the standard.  And in fact, the
standard actually contradicts itself here: the first sentence of
11.4 (Friends) says that a friend is a function or a class that
is not a member of the class, and templates are neither
functions nor classes.  14.5.3 (Friends, but in the chapter on
templates), says that a friend can be a function template or
class template, a specialization of a function template or class
template, or an ordinary (nontemplate) function or class.
There's a definite contradiction there.

I'm not sure what the compiler is doing in your case.  As I
said, I was surprised that it found an ambiguty.  If I
understand your code correctly, it should declare all of the
specializations of the template function as friend.  There is
also a syntax to declare just a particular instantiation as
friend, something like:
    friend ostream& operator<< <>( ... ) ;
I think (although maybe the declaration of the template must
precede the class definition).  I'm not really sure, however, as
I always use one of the techniques I mentionned in my first
post.

--
James Kanze (GABI Software)             email:james.ka@gmail.com
Conseils en informatique oriente objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34

On Jun 4, 2:16 am, James Kanze <james.ka@gmail.com> wrote:

James, thank you once again for your insight on this, it has been very
helpful.
Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc