By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

operator<< for standard output and templates

P: n/a
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 <classclass 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 <classclass 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,CrossOverPol icy,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

Jun 3 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Jun 4, 12:32 am, aaragon <alejandro.ara...@gmail.comwrote:
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 <classclass 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 <classclass 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,CrossOverPol icy,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.
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]
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: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 3 '07 #2

P: n/a
On Jun 3, 6:38 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 4, 12:32 am, aaragon <alejandro.ara...@gmail.comwrote:
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 <classclass 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 <classclass 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,CrossOverPol icy,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.
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]

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 orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
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 parametersbefore the keyword 'friend', aren't you
declaring this as a template function?
Once again, thanks for the answer.

Jun 4 '07 #3

P: n/a
On Jun 4, 6:34 am, aaragon <alejandro.ara...@gmail.comwrote:
On Jun 3, 6:38 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 4, 12:32 am, aaragon <alejandro.ara...@gmail.comwrote:
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 <classclass 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 <classclass 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.
};
[...]
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 parametersbefore 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 ambiguïty. 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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 4 '07 #4

P: n/a
On Jun 4, 2:16 am, James Kanze <james.ka...@gmail.comwrote:
On Jun 4, 6:34 am, aaragon <alejandro.ara...@gmail.comwrote:
On Jun 3, 6:38 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 4, 12:32 am, aaragon <alejandro.ara...@gmail.comwrote:
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 <classclass 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 <classclass 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.
};

[...]
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 parametersbefore 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 ambiguïty. 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 orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James, thank you once again for your insight on this, it has been very
helpful.

Jun 4 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.