Gems -- #include <gems.hpp>

T

Tomás

Let's write a header file which has all sorts of things in it which help a
programmer overcome what some people may see as "warts in C++", or maybe
things that are just more convenient or nicer to work with. For instance, if
you want to default initialise something, you have to know what kind of type
you're dealing with.

A) Intrinsic

int a = 0;
char* p = 0;
long r(0);

B) Array or POD Structure

SomeStructure blah = {};
int monkey[5] = {}

C) A class (i.e. a non-POD)

SomeClass blah;


However let's say you're writing a template function that hasn't got a clue
what it's working with... it needs a universal way of default initialising
something. The following class comes in handy:

template<class T>
class DefaultInitialised
{
public:

DefaultInitialised() : T() {}
};

typedef DefaultInitialised DefaultInitialized; //Keep the Americans happy!


Now here's our template function:

template<class T>
void Chocolate()
{
DefaultInitialised<T> object;

// do some stuff
}


But still we need to make room for intrinsics:

template<class T>
class DefaultInitialisedBearer
{
public:

T object;

DefaultInitialisedBearer() : object() {}
};


Now our template function could look like so:

template<class T>
void Chocolate()
{
DefaultInitialisedBearer<T> bearer;

T &object = bearer.object;

// do some stuff
}


I frequently find myself typing out such classes, when it'd be better for me
to just make a header file and throw it into the "standard include files
folder".

One gem I came across recently was posted by Ben; he gave a nice way of
working with what some people may think are arkward types. (I imagine that
some people here are quick to jump up and say that these types are only
arkward because a particular programmer isn't proficient enough to work with
it, but what they hey...).
You can return an array by reference as follows:

char ( &GetArray() )[6]
{
static char hello[] = "hello";

return hello;
}


An alternative was posted by Ben:


(Slightly modified by me)

template <class T>
class TypeSheath
{
typedef T actual;
typedef T& reference;
typedef T* pointer;
typedef const T* pointer_to_const;
};

TypeSheath<char[6]>::reference GetArray()
{
static char hello[] = "hello";
return hello;
}

While it's open opinion which is "better", I quite like the latter version.

So, anyone got any other ideas for what else to stick in this header file?
I'm going to put a little help file with it to explain the merits of each
little gem.


-Tomás
 
P

Phlip

Tomás said:
So, anyone got any other ideas for what else to stick in this header file?
I'm going to put a little help file with it to explain the merits of each
little gem.

Could you download Boost and read every source file, please?

;-)
 
R

red floyd

Tomás said:
However let's say you're writing a template function that hasn't got a clue
what it's working with... it needs a universal way of default initialising
something. The following class comes in handy:

template<class T>
class DefaultInitialised
{
public:

DefaultInitialised() : T() {}
};

typedef DefaultInitialised DefaultInitialized; //Keep the Americans happy!


This typedef is illegal.
 
B

benben

template said:
class DefaultInitialised
{
public:

DefaultInitialised() : T() {}
};

How would the above compile? T is neither a base nor a member you can't
initialize it.

Perhaps you meant:

template <typename T>
struct DefaultInitialized
{
T obj;
T():eek:bj(){}
};
typedef DefaultInitialised DefaultInitialized; //Keep the Americans happy!

From what you have written DefaultInitialised is, as far as i can see,
a *template*, not a class, not a type. And so you can't typedef it. It
should not compile.
Now here's our template function:

template<class T>
void Chocolate()
{
DefaultInitialised<T> object;

// do some stuff
}

In fact, if you want to default *contruct* an object of type T, just write:

T object;
But still we need to make room for intrinsics:

template<class T>
class DefaultInitialisedBearer
{
public:

T object;

DefaultInitialisedBearer() : object() {}
};


Now our template function could look like so:

template<class T>
void Chocolate()
{
DefaultInitialisedBearer<T> bearer;

T &object = bearer.object;

// do some stuff
}

Ok, I see your point and I think its not a bad idea after all...however
this might be too elaborating. How about:

T object = T();

It looks simpler and it definitely works well (given your compiler has
enough power to optimize away the temporary.)
I frequently find myself typing out such classes, when it'd be better for me
to just make a header file and throw it into the "standard include files
folder".

One gem I came across recently was posted by Ben; he gave a nice way of
working with what some people may think are arkward types. (I imagine that
some people here are quick to jump up and say that these types are only
arkward because a particular programmer isn't proficient enough to work with
it, but what they hey...).
You can return an array by reference as follows:

char ( &GetArray() )[6]
{
static char hello[] = "hello";

return hello;
}


An alternative was posted by Ben:


(Slightly modified by me)

template <class T>
class TypeSheath
{
typedef T actual;
typedef T& reference;
typedef T* pointer;
typedef const T* pointer_to_const;
};

TypeSheath<char[6]>::reference GetArray()
{
static char hello[] = "hello";
return hello;
}

While it's open opinion which is "better", I quite like the latter version.

Thanks for that. Better though, you may like to have a look at the boost
library. It provides a lot of (professionally written and well tested)
constructs that IMO more or less refines the C++ language.

If I am not too mistaken boost might as well be a superset of what you
are proposing.
So, anyone got any other ideas for what else to stick in this header file?
I'm going to put a little help file with it to explain the merits of each
little gem.


-Tomás


Ben
 
B

Ben Pope

benben said:
How would the above compile? T is neither a base nor a member you can't
initialize it.

Perhaps you meant:

template <typename T>
struct DefaultInitialized
{
T obj;
T():eek:bj(){}
};

Now, benben, I would have expected you to have learnt from his mistake:
Always paste from your editor, and attempt to compile the example.
Perhaps _you_ meant:

template <typename T>
struct DefaultInitialized {
T obj;
DefaultInitialized():eek:bj(){}
};

:p

Ben Pope
 
B

benben

Now, benben, I would have expected you to have learnt from his mistake:
Always paste from your editor, and attempt to compile the example.
Perhaps _you_ meant:

template <typename T>
struct DefaultInitialized {
T obj;
DefaultInitialized():eek:bj(){}
};

LOL indeed! What a mistake! My apologies!!!!
 
T

Tomás

Tomás posted:
Let's write a header file which has all sorts of things in it which
help a programmer overcome what some people may see as "warts in C++",
or maybe things that are just more convenient or nicer to work with.
For instance, if you want to default initialise something, you have to
know what kind of type you're dealing with.

A) Intrinsic

int a = 0;
char* p = 0;
long r(0);

B) Array or POD Structure

SomeStructure blah = {};
int monkey[5] = {}

C) A class (i.e. a non-POD)

SomeClass blah;


However let's say you're writing a template function that hasn't got a
clue what it's working with... it needs a universal way of default
initialising something. The following class comes in handy:

template<class T>
class DefaultInitialised
{
public:

DefaultInitialised() : T() {}
};

typedef DefaultInitialised DefaultInitialized; //Keep the Americans
happy!


Now here's our template function:

template<class T>
void Chocolate()
{
DefaultInitialised<T> object;

// do some stuff
}


But still we need to make room for intrinsics:

template<class T>
class DefaultInitialisedBearer
{
public:

T object;

DefaultInitialisedBearer() : object() {}
};


Now our template function could look like so:

template<class T>
void Chocolate()
{
DefaultInitialisedBearer<T> bearer;

T &object = bearer.object;

// do some stuff
}


I frequently find myself typing out such classes, when it'd be better
for me to just make a header file and throw it into the "standard
include files folder".

One gem I came across recently was posted by Ben; he gave a nice way of
working with what some people may think are arkward types. (I imagine
that some people here are quick to jump up and say that these types are
only arkward because a particular programmer isn't proficient enough to
work with it, but what they hey...).
You can return an array by reference as follows:

char ( &GetArray() )[6]
{
static char hello[] = "hello";

return hello;
}


An alternative was posted by Ben:


(Slightly modified by me)

template <class T>
class TypeSheath
{
typedef T actual;
typedef T& reference;
typedef T* pointer;
typedef const T* pointer_to_const;
};

TypeSheath<char[6]>::reference GetArray()
{
static char hello[] = "hello";
return hello;
}

While it's open opinion which is "better", I quite like the latter
version.

So, anyone got any other ideas for what else to stick in this header
file? I'm going to put a little help file with it to explain the merits
of each little gem.


-Tomás

Okay, I'll have a look a boost... but only because of peer pressure :p

-Tomás
 
T

Tomás

Ok, I see your point and I think its not a bad idea after all...however
this might be too elaborating. How about:

T object = T();

It looks simpler and it definitely works well (given your compiler has
enough power to optimize away the temporary.)


Try it like as follows:

std::eek:stringstream object = std::eek:stringstream();

Aren't private copy constructors a bitch!


The idea with "DefaultInitialisedBearer" was that you could default
initialise *anything*, whether it was an intrinsic, an array, a POD, a
non-POD class, or even a class which has a private copy contructor.

-Tomás
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top