Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to use operator<< to print a value?

17 views
Skip to first unread message

G. Wang

unread,
May 20, 2004, 7:23:47 AM5/20/04
to
Hi,

It is late in the night. My brain is not functioning. I couldn't
figure out how to do a simple thing. I want to write a template
function that take a single input parameter and print the value of
that parameter into a stream. Here is what I have:

template<typename T>
void Print( std::ostream& output, const T& a )
{
output << a;
}

Now the function works for all T whereas operator<<( std::ostream&,
const T& ) is defined. For those Ts that operator<< is not defined, I
would like function "Print" to print a sentence "do not know how to
print the value".

Anybody know how to modify the template function to print the value if
it can, and print "do not know how to print the value" otherwise?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Maxim Yegorushkin

unread,
May 20, 2004, 9:58:15 PM5/20/04
to
On 20 May 2004 07:23:47 -0400, G. Wang <visio...@hotmail.com> wrote:

> It is late in the night. My brain is not functioning. I couldn't
> figure out how to do a simple thing. I want to write a template
> function that take a single input parameter and print the value of
> that parameter into a stream. Here is what I have:
>
> template<typename T>
> void Print( std::ostream& output, const T& a )
> {
> output << a;
> }
>
> Now the function works for all T whereas operator<<( std::ostream&,
> const T& ) is defined. For those Ts that operator<< is not defined, I
> would like function "Print" to print a sentence "do not know how to
> print the value".
>
> Anybody know how to modify the template function to print the value if
> it can, and print "do not know how to print the value" otherwise?

Look at is_incrementable.hpp from boost for inspiration:

#include <iostream>

// resembles one from boost
template<bool> struct bool_ {};
typedef bool_<false> false_;
typedef bool_<true> true_;

namespace is_left_shiftable_ {

struct tag {};
struct any { template<class T> any(T const&); };
tag operator<<(any const&, any const&);

template<class T, class U>
struct is_left_shiftable_impl
{
typedef char(&no)[1];
typedef char(&yes)[2];

static no check(tag);
static yes check(...);

static T* t;
static U* u;

enum { value = (sizeof(yes) == sizeof(check(*t << *u))) };
typedef bool_<value> type;
};

} // namespace is_left_shiftable_

template<class T, class U>
struct is_left_shiftable : is_left_shiftable_::is_left_shiftable_impl<T, U>
{
};

template<class T>
std::ostream& print_impl(std::ostream& s, T const&, false_)
{
return s << "do not know how to print the value";
}

template<class T>
std::ostream& print_impl(std::ostream& s, T const& t, true_)
{
return s << t;
}

template<class T>
std::ostream& print(std::ostream& s, T const& t)
{
typedef typename is_left_shiftable<std::ostream, T>::type flag;
return print_impl(s, t, flag());
}

struct non_printable {};

int main()
{
print(std::cout, 1) << '\n';
print(std::cout, non_printable()) << '\n';
}

--
Maxim Yegorushkin

Ben Hutchings

unread,
May 21, 2004, 5:48:43 AM5/21/04
to
G. Wang wrote:
> Hi,
>
> It is late in the night. My brain is not functioning. I couldn't
> figure out how to do a simple thing.

Don't be so hard on yourself; this is actually not that simple.

> I want to write a template
> function that take a single input parameter and print the value of
> that parameter into a stream. Here is what I have:
>
> template<typename T>
> void Print( std::ostream& output, const T& a )
> {
> output << a;
> }
>
> Now the function works for all T whereas operator<<( std::ostream&,
> const T& ) is defined. For those Ts that operator<< is not defined, I
> would like function "Print" to print a sentence "do not know how to
> print the value".
>
> Anybody know how to modify the template function to print the value if
> it can, and print "do not know how to print the value" otherwise?

Terje Slettebř showed how to test for the presence of an operator in
<http://groups.google.com/groups?selm=q2vBa.9199%24KF1.136318%40amstwist00>.

Maxim Yegorushkin

unread,
May 21, 2004, 5:58:05 AM5/21/04
to
visio...@hotmail.com (G. Wang) wrote:

> It is late in the night. My brain is not functioning. I couldn't
> figure out how to do a simple thing. I want to write a template
> function that take a single input parameter and print the value of
> that parameter into a stream. Here is what I have:
>
> template<typename T>
> void Print( std::ostream& output, const T& a )
> {
> output << a;
> }
>
> Now the function works for all T whereas operator<<( std::ostream&,
> const T& ) is defined. For those Ts that operator<< is not defined, I
> would like function "Print" to print a sentence "do not know how to
> print the value".
>
> Anybody know how to modify the template function to print the value if
> it can, and print "do not know how to print the value" otherwise?

Look at is_incrementable.hpp from boost for inspiration:

#include <iostream>

namespace is_left_shiftable_ {

} // namespace is_left_shiftable_

struct non_printable {};

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

0 new messages