Re: template overloading of operator <<
On 7 Jul., 16:02, Vicky <mail....@gmail.com> wrote:
#include<iostream>
using namespace std;
template<class T>
class A
{
public:
enum Status
{
SUCCESS = 10000,
FAILURE = 10001,
UNKNOWN = 10002
};
};
typedef A<int> IntClass;
typedef A<string> StringClass;
template<class T>
inline std::ostream & operator<<(std::ostream & s, typename
A<T>::Status const & state)
This operator is unusable without providing an explicit
template parameter, because typename A<T>::Status
is an non-deducible context. The reason is simple:
The compiler cannot extract T from the argument.
{
switch (state)
{
case A<T>::SUCCESS: return s << "SUCCESS";
case A<T>::FAILURE: return s << "FAILURE";
case A<T>::UNKNOWN: return s << "UNKNOWN";
}
}
You should definitively add a default case for the switch, because
a user can create an enumeration value (e.g. UNKNOWN + FAILURE)
that has a different value as any of the currently specified ones.
int main()
{
IntClass::Status state = IntClass::SUCCESS;
cout << "Status " << state << endl;}
============================================================================
Output of the above program:
Status 10000
While the expected output was:
Status SUCCESS
the overloaded operator << was not invoked.
Could anyone please suggest some solution for the above?
Two approaches come into my mind, both ensure that
the IO inserter (aka operator<<) will be a non-template
function:
1) Move the inserter as an inline friend into template A like this:
template<class T>
class A
{
public:
enum Status
{
SUCCESS = 10000,
FAILURE = 10001,
UNKNOWN = 10002
};
friend std::ostream & operator<<(std::ostream & s,
Status const & state)
{
switch (state)
{
case A<T>::SUCCESS: return s << "SUCCESS";
case A<T>::FAILURE: return s << "FAILURE";
case A<T>::UNKNOWN: return s << "UNKNOWN";
}
}
};
2) Move the enum into a non-template base class (or namespace)
and provide a free IO inserter like this:
struct B {
enum Status
{
SUCCESS = 10000,
FAILURE = 10001,
UNKNOWN = 10002
};
};
inline std::ostream & operator<<(std::ostream & s,
B::Status const & state)
{
switch (state)
{
case B::SUCCESS: return s << "SUCCESS";
case B::FAILURE: return s << "FAILURE";
case B::UNKNOWN: return s << "UNKNOWN";
}
}
template<class T>
class A : public B
{
public:
};
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! ]