473,396 Members | 2,017 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

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 <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
4 1754
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: franky.backeljauw | last post by:
Hello, I have a problem with using a copy constructor to convert an object of a templated class to object of another templated class. Let me first include the code (my question is below): ...
4
by: Guenther Brunthaler | last post by:
Hi template specialists, I have a problem with the code listed below. What I wanted to do is defining an operator<< that is able to output a 'matrix<ELEMENT_T, INDEX_T>::subrange' object into...
2
by: Julian | last post by:
I would like to have output from my program to be written to cout as well as a file. (actually, i want several other output options but this should explain my problem in the simplest way). I have...
3
by: Carlo Capelli | last post by:
I found a change in the following code, that behaved correctly in VC++ 6. #include <strstream> using namespace std; void main() { char x; ostrstream(x, 100) << "pippo" << "pluto" << ends;...
4
by: homsan toft | last post by:
I've tried the below code with MSVC and Comeau online compiler. Both complain that operator<< for Outer<part<size_t> >::inner is not defined. So how do I declare it without doing full...
7
by: glen | last post by:
Hi. I'm using GCC 4.1.1, which I mention since I don't know if this is a compiler issue, or me not understanding some subtlety in the standard. The code below compiles fine under vc++, but I'm...
0
by: Adrian | last post by:
Hi All, I am trying to create an output operator that doesnt rely on the stream type and is also polymorphic. Is there a way to combine these 2 methods so that the polymorphic output operator...
3
by: Martin T. | last post by:
Hello. I tried to overload the operator<< for implicit printing of wchar_t string on a char stream. Normally using it on a ostream will succeed as std::operator<<<std::char_traits<char> will...
4
by: =?ISO-8859-1?Q?Dar=EDo_Griffo?= | last post by:
I'm having an error with this code #include <iostream> template < typename Tclass TestOpTemplate { public: friend std::ostream& operator<< <>(std::ostream& os, const TestOpTemplate<T>& m);...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.