Re: compilation error with overloaded output operator
* James Kanze <james.ka...@gmail.com> wrote:
On Nov 11, 2:54 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
The following program is ONLY for learning C++.
Consider the program x.cpp:
#include <cstdlib>
#include <iostream>
using namespace std;
template <typename Type>
inline ostream& operator<<(ostream& os, Type obj)
{
Type temp;
temp = obj;
return os;
}
int main()
{
int x = 100;
cout << x;
cout << endl;
cout << 10;
cout << endl;
cout << "Enter some integers: ";
cout << endl;
return EXIT_SUCCESS;
}
When I compile this program as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
I get compilation error for the line
cout << "Enter some integers: ";
Here are the actual compilation errors:
x.cpp: In function `int main()':
x.cpp:22: error: ambiguous overload for 'operator<<' in 'std::cout <<
"Enter some integers: "'
/usr/lib/gcc/i386-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
bits/ostream.tcc:98: note: candidates are: std::basic_ostream<_CharT,
_Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i386-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
bits/ostream.tcc:284: note: std::basic_ostream<_CharT,
_Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*)
[with _CharT = char, _Traits = std::char_traits<char>]
x.cpp:8: note: std::ostream& operator<<(std::ostream&,
Type) [with Type = const char*]
/usr/lib/gcc/i386-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
bits/ostream.tcc:612: note: std::basic_ostream<char,
_Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const
char*) [with _Traits = std::char_traits<char>]/usr/lib/gcc/i386-redhat-
linux/3.4.3/../../../../include/c++/3.4.3/bits/ostream.tcc:567:
note: std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*)
[with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i386-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
bits/ostream.tcc:534: note: std::basic_ostream<_CharT,
_Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const
_CharT*) [with _CharT = char, _Traits = std::char_traits<char>]
Question:
The ambiguity error is reported by g++ for the line
cout << "Enter some integers: ";
because this program has the function defined for the overloaded
operator<<() and the standard library also
defines it - multiple functions for operator<<() and hence the error.
But what I do not understand is that why similar ambiguity error is
not reported for the lines
cout << x;
cout << endl;
cout << 10;
Kindly explain.
The short answer: operator<<(int) and operator<<(ios_base&
(*pf)(ios_base&)) are member functions, operator<<(char const*)
is a non-member template function. You're operator<< is
instantiated in all cases, and results in an exact match.
When a template function and a non template function are both
equally good, the non template is chosen, and there is no
ambiguity. In the case of operator<<(char const*), however, the
choice is between the instantiations of two different templates,
so there is no tie-breaker, and the overload is ambiguous.
--
James Kanze
The following program is for understanding purpose only. I will NOT
write such a program.
Consider the following program which has a non-template class
with a member-function-template for the overloaded operator+=() and a
non-template, free-function for the same operator.(These two functions
differ in return-type, just for understanding purpose).
#include <cstdlib>
#include <ostream>
#include <iostream>
using namespace std;
class Test
{
public:
explicit Test(int arg = 0);
Test(const Test& rhs);
Test& operator=(const Test& rhs);
ostream& write(ostream& os) const;
template <typename Type>
Test& operator+=(const Type& rhs);
private:
int val;
};
inline Test::Test(int arg) : val(arg)
{
}
inline Test::Test(const Test& rhs) : val(rhs.val)
{
}
inline Test& Test::operator=(const Test& rhs)
{
if (this != &rhs)
val = rhs.val;
return *this;
}
inline ostream& Test::write(ostream& os) const
{
return os << val;
}
template <typename Type>
inline Test& Test::operator+=(const Type& rhs)
{
cout << "Inside Test::operator+=()" << endl;
return *this;
}
inline ostream& operator<<(ostream& os, const Test& obj)
{
return obj.write(os);
}
inline void operator+=(Test& lhs, long rhs)
{
cout << "Inside free function: operator+=()" << endl;
return;
}
int main()
{
Test first(100);
cout << "Inside main(): before calling operator+=()"
<< endl;
first += 2000L;
cout << "Inside main(): after calling operator+=()"
<< endl;
return EXIT_SUCCESS;
}
Note in this program that in the line
inline void operator+=(Test& lhs, long rhs)
the first parameter is a plain reference(not a reference to const).
This is written so, because, then only both the member-function-
template operator+=() nad the free-non-teemplate-function operator+=()
will be considered for the following statement in main():
first += 2000L;
When this program, y.cpp, is compiled with g++3.4.3 as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp
It generates the following two warnings, which is expceted.
y.cpp:57: warning: unused parameter 'lhs'
y.cpp:57: warning: unused parameter 'rhs'
The output of this program is
Inside main(): before calling operator+=()
Inside free function: operator+=()
Inside main(): after calling operator+=()
The second line in the output means that the non-template, free-
function for the overloaded operator+=() is chosen and the
member-function namely:
template <typename Type>
inline Test& Test::operator+=(const Type& rhs)
is not used because:
For the following statement in main(),
first += 2000L;
both the member-function-template Test::operator+=() and the free-non-
template-function operator+=() are valid. Since you have pointed that
when both a template and a non-template function match exactly, the
non-template version should be chosen, the free-non-template-function
for the overloaded operator+=() has been used.
Is this what you have mentioned in your reply ? Have I understood it
correctly ?
Kindly explain.
Thanks
V.Subramanian