473,396 Members | 1,975 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.

Template for POD types only

Is it possible to create a template for POD types only?

I want to code something like this:

class Object // base class
{
virtual void WriteToStream(Stream &) = 0;
};

class Stream
{

template <typename TPOD>
inline void operator << (TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (Object &Obj)
{
Obj.WriteToStream(*this);
}

};

And I want compiler to use first method to write PODs and second to
write derived from Object (not Objects itself but derived from
Object!). Is it possible to tell compiler to use first method only for
PODs?

Dec 28 '05 #1
8 3781
Are you saying you want the compiler to detect that a type is a POD
type, or do you intend all POD types to inherit from a common base
class? If that's all you want, just use partial template
specialization (with proper syntax -- go look it up) and you're all
set.

Luke

Dec 28 '05 #2

Raider wrote:
Is it possible to create a template for POD types only?

I want to code something like this:

class Object // base class
{
virtual void WriteToStream(Stream &) = 0;
};

class Stream
{

template <typename TPOD>
inline void operator << (TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (Object &Obj)
{
Obj.WriteToStream(*this);
}

};

And I want compiler to use first method to write PODs and second to
write derived from Object (not Objects itself but derived from
Object!). Is it possible to tell compiler to use first method only for
PODs?


Here's some example code using boost is_pod:

#include <iostream>
#include <string>

#include "boost\type_traits\is_pod.hpp"

using namespace std;

template <typename T, bool ISPOD = boost::is_pod<T>::value> struct
base_t {};

template <typename T> struct base_t<T,false>
{
void operator << (const T &Obj){ cout << "Is Not POD " << Obj <<
endl;}
};

template <typename T> struct base_t<T,true>
{
void operator << (const T &POD){cout << "Is POD " << POD << endl;}
};

class Stream
{
public:
template<typename T>
void operator << (const T &t)
{
base_t<T>() << t;
}
};

int main(int argc, char* argv[])
{
Stream My_Stream;
My_Stream << 123;

My_Stream << string("Hello");

Dec 28 '05 #3
Luke, I want the compiler to use RawWrite() for the first type and
SecondType::WriteToStream() for the second one:

enum FirstType
{
Bla, Bla2,
};

class SecondType : public Object
{
virtual void WriteToStream(Stream &);
}

....

Stream s;
FirstType o1;
SecondType o2;

s << o1;
s << o2;

Dec 28 '05 #4
Thanks Axter! I'll try to get boost and use your code.

Dec 28 '05 #5
In article <11**********************@g47g2000cwa.googlegroups .com>,
"Raider" <sr*****@yandex.ru> wrote:
Is it possible to create a template for POD types only?

I want to code something like this:

class Object // base class
{
virtual void WriteToStream(Stream &) = 0;
};

class Stream
{

template <typename TPOD>
inline void operator << (TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (Object &Obj)
{
Obj.WriteToStream(*this);
}

};

And I want compiler to use first method to write PODs and second to
write derived from Object (not Objects itself but derived from
Object!). Is it possible to tell compiler to use first method only for
PODs?


Here's another approach (in addition to Axter's good suggestion). It
also requires boost:

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

class Stream;

class Object // base class
{
public:
virtual void WriteToStream(Stream &) const = 0;
};

class Stream
{
public:
template <typename TPOD>
inline
typename boost::enable_if<boost::is_pod<TPOD> >::type
operator << (const TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (const Object &Obj)
{
Obj.WriteToStream(*this);
}

};

This approach saves you the trouble of having to work through an
implementation class (base_t in Axter's example). It more directly
reflects your goal of restricting the template parameter TPOD to just
pods, while allowing overloading to other operator<<.

-Howard
Dec 28 '05 #6
Okay, still a slight ambiguity, sorry. If I take you literally,
partial template specialization is still the answer -- it's certainly
sufficient for the example code you've posted. It's also sufficient if
you have a common "Object" base class for everything that isn't a POD.
If that wasn't what you meant, then I'd follow other people's
suggestion to use boost::is_pod<T>. The Boost libraries are of
phenomenal importance, so you should install them and learn to love
them regardless of whether you wind up needing them in this particular
case. Better yet, go see how is_pod is implemented. :)

I'll offer my own version of "how to do it with boost," though I must
apologize that I can't test this code myself right now as I'm in the
middle of a RedHat install, and attempting this with MSVC 6.0 sounds
like a cruel joke to play on myself and that dated compiler. Anyway,
this is the code I'd generate:

#include <string>
#include <boost/type_traits/is_pod.hpp> // <-- should use forward
slashes and angle brackets as here
#include <boost/static_assert.hpp>

class Stream {
private:
template <class T> class Stream & rawWrite(
friend template <class T, bool isPod> operator<<(Stream & os, T
obj);
};

template <class T, bool isPod>
Stream & operator<<(Stream & os, T nonPodObj) {
nonPodObj.writeToStream(os);
return os;
}

template <class T>
Stream & operator<< <T, true>(Stream & os, T pod) {
BOOST_STATIC_ASSERT(boost::is_pod<T>::value);
os.rawWrite(&pod, sizeof(T));
}

class Base {
public:
Stream & writeToStream(Stream & os);
};

/*** END CODE LISTING ***/

The above should work (again, untested -- sorry) as long as you don't
directly subvert it -- if you're worried about someone doing that, you
can put in another static assertion to guard against it, or structure
it a little differently by delegating to a helper based on the value of
is_pod.

A couple of notes on some pitfalls to avoid from the other (otherwise
perfectly helpful) suggestions you received:
* Never do a "using namespace std" declaration at a wider scope than an
individual function. It pollutes the global namespace and completly
defeats the purpose of the std namespace. Make use of using-directives
(e.g. "using std::string") instead, or explicitly qualify upon use.
* operator<<'s signature should be as I've given it -- it takes a
reference (non-const) to the stream as well as the object, and returns
the stream by reference. If you don't do it this way, you can't chain
them together. As such, it should not be a member function, either.
* Don't #include <iostream> if you're not using it.
* Make sure that you know the criteria is_pod uses, thoroughly. Check
the standard if you don't know the precise definition (it's not
entirely obvious), or the boost::is_pod documentation.

There are a lot of variants on how exactly to do the decision logic
within the bounds of partial template specialization. I heartily
recommend "Modern C++ Design" by Andrei Alexandrescu (waves @ Andrei --
I was a CS undergrad at UW during his grad stint there, I believe) and
"C++ Template Metaprogramming" by Abrahams and Gurtovoy.

Luke

Dec 28 '05 #7

Howard Hinnant wrote:
In article <11**********************@g47g2000cwa.googlegroups .com>,
"Raider" <sr*****@yandex.ru> wrote:
Is it possible to create a template for POD types only?

I want to code something like this:

class Object // base class
{
virtual void WriteToStream(Stream &) = 0;
};

class Stream
{

template <typename TPOD>
inline void operator << (TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (Object &Obj)
{
Obj.WriteToStream(*this);
}

};

And I want compiler to use first method to write PODs and second to
write derived from Object (not Objects itself but derived from
Object!). Is it possible to tell compiler to use first method only for
PODs?


Here's another approach (in addition to Axter's good suggestion). It
also requires boost:

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

class Stream;

class Object // base class
{
public:
virtual void WriteToStream(Stream &) const = 0;
};

class Stream
{
public:
template <typename TPOD>
inline
typename boost::enable_if<boost::is_pod<TPOD> >::type
operator << (const TPOD &POD)
{
RawWrite(&POD, sizeof(TPOD));
}

inline void operator << (const Object &Obj)
{
Obj.WriteToStream(*this);
}

};

This approach saves you the trouble of having to work through an
implementation class (base_t in Axter's example). It more directly
reflects your goal of restricting the template parameter TPOD to just
pods, while allowing overloading to other operator<<.


**boost::enable_if**
Very nice trick.

Dec 28 '05 #8
"Axter" <go****@axter.com> writes:
Here's some example code using boost is_pod:

#include <iostream>
#include <string>

#include "boost\type_traits\is_pod.hpp"


Should be "boost/type_traits/is_pos.hpp"

(Yes on windows too!)

/Niklas Norrthon
Dec 29 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Surya Kiran | last post by:
Hi all, I've written a function template. say template <class T> fn (T var) { ... } Is there any way, from within the function, can we check what type of argument we've passed on to the...
17
by: Jacek Dziedzic | last post by:
Hello! I have a templated class that serves as a simple vector of elements. template <typename T> class simple_vector : public math_object { // ... lots of simple_vector operations // the...
31
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will...
9
by: Jon Wilson | last post by:
I have a class which needs to accumulate data. The way we get this data is by calling a member function which returns float on a number of different objects of different type (they are all the...
8
by: Thomas Heller | last post by:
I need to convert C preprocessor definitions into python code. The definitions are dumped out of gccxml (see http://www.gccxml.org) , running over the windows header files (for example). This...
9
by: Ann Huxtable | last post by:
I have the following code segment - which compiles fine. I'm just worried I may get run time probs - because it looks like the functions are being overloaded by the return types?. Is this Ok: ? ...
10
by: Suki | last post by:
Hi, I'm writing a templated class, and i dont want to use the class otherthan for some predetermined types, say, int, double etc. This class has no meaning for typenames other than those few. ...
12
by: mlimber | last post by:
This is a repost (with slight modifications) from comp.lang.c++.moderated in an effort to get some response. I am using Loki's Factory as presented in _Modern C++ Design_ for message passing in...
6
by: Hendrik Schober | last post by:
Hi, I have a problem with extending some existing code. In a simplified form, the problem looks like this: I have four types, A, B, C, and D. Each A refers to zero, one, or more B's and each...
9
by: Marco Nef | last post by:
Hi there I'm looking for a template class that converts the template argument to a string, so something like the following should work: Convert<float>::Get() == "float"; Convert<3>::Get() ==...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
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
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.