ATL::CString and operator<<

K

Kiarra

The operators << and >> are not available for the atl version of CString, so
assuming I derive a class from CString, say CStringS, how do I add the
operator<< to the class ?

I have tried various methods, some sort of work, for CStrings but go
horribly wrong when used with _T("...") as they are constant chars, and a
temporary object gets created and then variables get lost, or others give
compiler errors of

error C2678: binary '<<' : no operator found which takes a left-hand operand
of type 'CStringS' (or there is no acceptable conversion)
1> \harness\cstrings.h(28): could be 'std::blush:stream &operator
<<(std::blush:stream &,CStringS)' [found using argument-dependent lookup]


even though there is only overloaded operator.

What I need to do is something like:

CStringS h = _T("Hello");
CStringS w = _T("World");
CStringS cs;


cs << h << _T(" Sunny ") << w << std::endl;

cout << cs;

Any ideas ? Ive been trying to get this to work for sometime now but its
really causing me a huge headache and there is nothing on the web.

Thanks :)
 
C

Cholo Lennon

Kiarra said:
The operators << and >> are not available for the atl version of
CString, so assuming I derive a class from CString, say CStringS, how
do I add the operator<< to the class ?

I have tried various methods, some sort of work, for CStrings but go
horribly wrong when used with _T("...") as they are constant chars,
and a temporary object gets created and then variables get lost, or
others give compiler errors of

error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CStringS' (or there is no acceptable conversion)
1> \harness\cstrings.h(28): could be 'std::blush:stream &operator
<<(std::blush:stream &,CStringS)' [found using argument-dependent lookup]


even though there is only overloaded operator.

What I need to do is something like:

CStringS h = _T("Hello");
CStringS w = _T("World");
CStringS cs;


cs << h << _T(" Sunny ") << w << std::endl;

cout << cs;

Any ideas ? Ive been trying to get this to work for sometime now but
its really causing me a huge headache and there is nothing on the web.

You don't need to derive a new class from CString to add a '<<' minimal support. Just add some non-member '<<' operators:

inline CString& operator<<(CString& rStr, CString::pCXSTR pszStr)
{
return rStr += pszStr;
}

inline CString& operator<<(CString& rStr, CString::XCHAR ch)
{
return rStr += ch;
}


std::endl is a function, not a constant. To allow some interaction between C++ standard library and ATL/MFC you have to add another
'<<' operator where the 2nd parameter is a function pointer (check std::endl definition to have an idea of this).

If you want to add '<<' support to any class, the easiest way is to use std::stringstream and templates:

struct Foo
{
...
template<typename T>
Foo& operator<<(const T& value)
{
std::stringstream ss;
ss << value;
m_strValue += ss.str();
return *this;
}

const std::string& GetValue() const
{
return m_strValue;
}

private:
std::string m_strValue;
};


Regards

PS: The correct groups for this question are microsoft.public.vc.atl and/or microsoft.public.vc.mfc (CString is the same for
ATL/MFC).
 
K

Kiarra

Awesome!

Thanks so much for clarification and examples. Ive never realy done that
much in C++ so this making more sense of other things too! :)

Ki

Cholo Lennon said:
Kiarra said:
The operators << and >> are not available for the atl version of
CString, so assuming I derive a class from CString, say CStringS, how
do I add the operator<< to the class ?

I have tried various methods, some sort of work, for CStrings but go
horribly wrong when used with _T("...") as they are constant chars,
and a temporary object gets created and then variables get lost, or
others give compiler errors of

error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CStringS' (or there is no acceptable conversion)
1> \harness\cstrings.h(28): could be 'std::blush:stream &operator
<<(std::blush:stream &,CStringS)' [found using argument-dependent lookup]


even though there is only overloaded operator.

What I need to do is something like:

CStringS h = _T("Hello");
CStringS w = _T("World");
CStringS cs;


cs << h << _T(" Sunny ") << w << std::endl;

cout << cs;

Any ideas ? Ive been trying to get this to work for sometime now but
its really causing me a huge headache and there is nothing on the web.

You don't need to derive a new class from CString to add a '<<' minimal support. Just add some non-member '<<' operators:

inline CString& operator<<(CString& rStr, CString::pCXSTR pszStr)
{
return rStr += pszStr;
}

inline CString& operator<<(CString& rStr, CString::XCHAR ch)
{
return rStr += ch;
}


std::endl is a function, not a constant. To allow some interaction between C++ standard library and ATL/MFC you have to add another
'<<' operator where the 2nd parameter is a function pointer (check std::endl definition to have an idea of this).

If you want to add '<<' support to any class, the easiest way is to use std::stringstream and templates:

struct Foo
{
...
template<typename T>
Foo& operator<<(const T& value)
{
std::stringstream ss;
ss << value;
m_strValue += ss.str();
return *this;
}

const std::string& GetValue() const
{
return m_strValue;
}

private:
std::string m_strValue;
};


Regards

PS: The correct groups for this question are microsoft.public.vc.atl and/or microsoft.public.vc.mfc (CString is the same for
ATL/MFC).
 
Top