473,503 Members | 1,700 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Templated Classes question (what to do with char*)

Hi All (first time caller, long time listener),
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:

I need to create a templated class that accepts any type. Easy
enough I though, like this:

template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
~Foo(void){}
void SetData(Type d){ data = d; }
}

But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense. Thanks!

Feb 4 '07 #1
12 1753
Ro**********@gmail.com wrote:
Hi All (first time caller, long time listener),
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:

I need to create a templated class that accepts any type. Easy
enough I though, like this:

template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
I would prefer initialization:

Foo ( Type d )
: data ( d )
{}
~Foo(void){}
void SetData(Type d){ data = d; }
Setter and Getter functions are usually a smell.
}
missing ";"

But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense.
Sure does: You can use a partial specialization:

template <>
class Foo< char* {

char* data;

Foo ( char* str ) :
: data ( new char [ strlen( str ) + 1 ] )
//FIXME: maybe off by one
{
strcpy( I forgot the argument order )
// FIXME: I don't know whether strcpy takes care of terminating 0.
}

...

};

or something like that.

Note however, that

a) you would need to do this for signed char and unsigned char, too.
b) The default implementation is very likely to do the wrong thing for any
pointer type.
You might want to have a look into enable_if and disable_if from boost to
see whether you can prevent Foo<T*to be instantiated for any T but
char/signed char/unsigned char.

Best

Kai-Uwe Bux
Feb 4 '07 #2
On Feb 3, 8:54 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Robert.Ho...@gmail.com wrote:
Hi All (first time caller, long time listener),
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:
I need to create a templated class that accepts any type. Easy
enough I though, like this:
template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);

I would prefer initialization:

Foo ( Type d )
: data ( d )
{}
~Foo(void){}
void SetData(Type d){ data = d; }

Setter and Getter functions are usually a smell.
}

missing ";"
But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense.

Sure does: You can use a partial specialization:

template <>
class Foo< char* {

char* data;

Foo ( char* str ) :
: data ( new char [ strlen( str ) + 1 ] )
//FIXME: maybe off by one
{
strcpy( I forgot the argument order )
// FIXME: I don't know whether strcpy takes care of terminating 0.
}

...

};

or something like that.

Note however, that

a) you would need to do this for signed char and unsigned char, too.
b) The default implementation is very likely to do the wrong thing for any
pointer type.

You might want to have a look into enable_if and disable_if from boost to
see whether you can prevent Foo<T*to be instantiated for any T but
char/signed char/unsigned char.

Best

Kai-Uwe Bux
I dont understand, by doing the partial specialization anytime I made
a class Foo<char*it would use that specialization and any other time
it would use Foo<Type>. Is that what you mean? So basically hard code
the template function for types that are pointers?

Feb 4 '07 #3
In article <11**********************@q2g2000cwa.googlegroups. com>,
Ro**********@gmail.com says...
Hi All (first time caller, long time listener),
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:

I need to create a templated class that accepts any type. Easy
enough I though, like this:

template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
~Foo(void){}
void SetData(Type d){ data = d; }
}

But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense. Thanks!
Sure -- you can explicitly specialize your template over type char *,
and have the explicit specialization do the right thing. You'd start
with the code above (after fixing typos, such as in the ctor), and then
add an explicit specialization:

template<>
class Foo<char *{
// ...
};

Making this code exception safe WILL be decidedly non-trivial. Unless
you're quite experienced with exception safety, I'd recommend reading
items 8-13 of _Exceptional C++_ before you implement this code.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Feb 4 '07 #4
In article <eq*********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
Sure does: You can use a partial specialization:

template <>
class Foo< char* {
Just a minor note on terminology: this is an explicit specialization. A
partial specialization is...partial. For example:

template <class T, class U>
class Foo {
// ...
};

template <class T>
class Foo<char{
// ...
};

In this case, the specialization is only partial -- one parameter has a
specified type, but the other is still generic. You can only partially
specialize a template that has at least two template parameters.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Feb 4 '07 #5
On Feb 3, 9:27 pm, Jerry Coffin <jcof...@taeus.comwrote:
In article <eq3eci$2...@murdoch.acc.Virginia.EDU>, jkherci...@gmx.net
says...

[ ... ]
Sure does: You can use a partial specialization:
template <>
class Foo< char* {

Just a minor note on terminology: this is an explicit specialization. A
partial specialization is...partial. For example:

template <class T, class U>
class Foo {
// ...

};

template <class T>
class Foo<char{
// ...

};

In this case, the specialization is only partial -- one parameter has a
specified type, but the other is still generic. You can only partially
specialize a template that has at least two template parameters.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Thank you very much. You guys were extremely helpful and clear. Cheers

Feb 4 '07 #6
Ro**********@gmail.com wrote:
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:

I need to create a templated class that accepts any type. Easy
enough I though, like this:

template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
~Foo(void){}
void SetData(Type d){ data = d; }
}

But what if the type is char*?
Don't do that. Use std::string instead.
Is there a way I can tell it is and therefore strcpy into data
instead of straight copy of the pointer so that when the inputted
string into SetData loses scope I can retain it?
Yes there is a way to do that, but it opens up the question, what about
pointers to other things?

template< typename Type >
class Foo
{
Type data;
public:
Foo( Type d ) {
data = d;
}
~Foo() { }

void SetData( Type d ) {
data = d;
}
};

template<>
class Foo < char* >
{
char* data;
public:
Foo( const char* d ): data( 0 ) {
SetData( d );
}
Foo( const Foo& o ): data( 0 ) {
SetData( o.data );
}
~Foo() {
delete [] data;
}
Foo& operator=( const Foo& o ) {
SetData( o.data );
return *this;
}
void SetData( const char* d ) {
char* tmp = data;
data = new char[ strlen( d ) ];
strcpy( data, d );
delete [] tmp;
}
};
Feb 4 '07 #7
In article <da****************************@news.west.earthlin k.net>,
"Daniel T." <da******@earthlink.netwrote:
template<>
class Foo < char* >
{
char* data;
public:
Foo( const char* d ): data( 0 ) {
SetData( d );
}
Foo( const Foo& o ): data( 0 ) {
SetData( o.data );
}
~Foo() {
delete [] data;
}
Foo& operator=( const Foo& o ) {
SetData( o.data );
return *this;
}
void SetData( const char* d ) {
char* tmp = data;
data = new char[ strlen( d ) ];
strcpy( data, d );
delete [] tmp;
}
};
I was caught by the off-by-one error in SetData. It should be "data =
new char[ strlen( d ) + 1 ];" Yet another reason to use std::string.
Feb 4 '07 #8
Ro**********@gmail.com wrote:
On Feb 3, 8:54 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
>Robert.Ho...@gmail.com wrote:
>>Hi All (first time caller, long time listener),
I've stumbled across a problem that I have yet to figure out,
although Im sure I'll kick myself when I figure it out. Here it is:
I need to create a templated class that accepts any type. Easy
enough I though, like this:
template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
I would prefer initialization:

Foo ( Type d )
: data ( d )
{}
>> ~Foo(void){}
void SetData(Type d){ data = d; }
Setter and Getter functions are usually a smell.
>>}
missing ";"
>>But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense.
Sure does: You can use a partial specialization:

template <>
class Foo< char* {

char* data;

Foo ( char* str ) :
: data ( new char [ strlen( str ) + 1 ] )
//FIXME: maybe off by one
{
strcpy( I forgot the argument order )
// FIXME: I don't know whether strcpy takes care of terminating 0.
}

...

};

or something like that.

Note however, that

a) you would need to do this for signed char and unsigned char, too.
b) The default implementation is very likely to do the wrong thing for any
pointer type.

You might want to have a look into enable_if and disable_if from boost to
see whether you can prevent Foo<T*to be instantiated for any T but
char/signed char/unsigned char.

Best

Kai-Uwe Bux

I dont understand, by doing the partial specialization anytime I made
a class Foo<char*it would use that specialization and any other time
it would use Foo<Type>. Is that what you mean? So basically hard code
the template function for types that are pointers?
If you have a general solution for any pointer type, you can use partial
specialization to get just pointer types:

template <typename Type>
class Foo
{
// implementation goes here.
} ;

template <typename Type>
class Foo<Type *>
{
// implementation for pointer types goes here.
} ;

// Not necessary if the above would work for char *.
template <>
class Foo<char *>
{
// implementation for char * goes here.
} ;

--
Alan Johnson
Feb 4 '07 #9
If you have a general solution for any pointer type, you can use partial
specialization to get just pointer types:

template <typename Type>
class Foo
{
// implementation goes here.

} ;

template <typename Type>
class Foo<Type *>
{
// implementation for pointer types goes here.

} ;

// Not necessary if the above would work for char *.
template <>
class Foo<char *>
{
// implementation for char * goes here.

} ;

--
Alan Johnson- Hide quoted text -

- Show quoted text -
// Not necessary if the above would work for char *.
It still seems to me that you would need to specify the char* aside
from the pointer implementation . Maybe thats what you mean and a
typo, not sure.

Feb 4 '07 #10
Ro**********@gmail.com wrote:
>If you have a general solution for any pointer type, you can use partial
specialization to get just pointer types:

template <typename Type>
class Foo
{
// implementation goes here.

} ;

template <typename Type>
class Foo<Type *>
{
// implementation for pointer types goes here.

} ;

// Not necessary if the above would work for char *.
template <>
class Foo<char *>
{
// implementation for char * goes here.

} ;

--
Alan Johnson- Hide quoted text -

- Show quoted text -

>// Not necessary if the above would work for char *.

It still seems to me that you would need to specify the char* aside
from the pointer implementation . Maybe thats what you mean and a
typo, not sure.
The comment was just meant to imply that C++ wouldn't require you to
have the explicit specialization. I've no idea what specific problem
you are trying to solve. It may be that your solution for a Type * (for
some generic Type) would also work for a a char *, in which case you
would not need an explicit specialization for char *. If that is not
the case, then you do, of course, need the explicit specialization for
char *.

--
Alan Johnson
Feb 4 '07 #11
Ro**********@gmail.com :
>
I need to create a templated class that accepts any type. Easy
enough I though, like this:

But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it? Hopefully that makes sense. Thanks!
Any type will work with your templated class. But as i can understand, you
want to manage any object pointer point to - copy if pointer copying, delete
if pointer deleted etc. C++ type "pointer" does not allow it. There are
special classes, that can do it - common wrappers as auto_ptr or special for
"char*" classes as cstring. Use the classes as parameters instead of POD
pointers.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 8 '07 #12
Ro**********@gmail.com writes:
I need to create a templated class that accepts any type. Easy
enough I though, like this:

template<typename Type>
class Foo
{
Type data;
Foo(Type d){ data = d);
~Foo(void){}
void SetData(Type d){ data = d; }
}

But what if the type is char*? Is there a way I can tell it is and
therefore strcpy into data instead of straight copy of the pointer so
that when the inputted string into SetData loses scope I can retain
it?
You can use another class as template's parameter which specifies
copying functions and specializations, ie.:

#v+
template<class T>
class foo_copier {
static void init(T &dest, const T&src) {
dest = src;
}

static void copy(T &dest, const T&src) {
dest = src;
}

static void done(T &dest) {
/* nothing */
}
};

template<>
class foo_copier<char *{
static void init(T &dest, const T&src) {
dest = 0;
copy(dest, src);
}

static void copy(T &dest, const T&src) {
delete[] dest;
size_t len = strlen(src) + 1;
dest = new char[len];
memcpy(dest, src, len);
}

static void done(T &dest) {
delete[] dest;
}
};
#v-

and then your class would look like:

#v+
template<class T, class copier = foo_copier<T
class Foo {
T data;
public:
Foo(const T &d) {
copier::init(data, d);
}

~Foo() {
copier::done(data);
}

void setData(const T &d) {
copier::copy(data, d);
}
};
#v-

This way users could define their own copier classes with their own
chosen behaviour. Note however, that some compilers do not support
default template arguments (ie. the part " = foo_copier<T").

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Feb 13 '07 #13

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

Similar topics

3
6561
by: tirath | last post by:
Hi all, I have a templated class that derives from a non-templated abstract class. How do I then cast a base class pointer to a <templated> derived class pointer in a generalised fashion? ...
1
1849
by: Rich | last post by:
Hi, I have a query regarding VC6 and its handling of templated copy constructors. Here goes: Take a look at the following code sample... template<class _Ty, size_t t_uiSize = 10 > class...
3
2715
by: case2005 | last post by:
Can anyone help with the following, I don't know if it's possible, but I'm certain there must be a standard way of dealing with this. I have the following: template<typename FooBar, typename...
4
1506
by: __PPS__ | last post by:
suppose I have class that has templated operator. I want to have a few overloads/template specializations for different types. Basicly, the biggest problem I have is to be able to have this: ...
3
1549
by: Rickarazzi | last post by:
This is a problem that arose while using GNU G++ 3.4.5 under Linux. The problem is: How to get a pointer value from a templated object inside a class? Normally, I would add an '&' can carry on. ...
2
1676
by: mattjgalloway | last post by:
I'm having some problems with a templated member function of a templated class. Unfortunately I can't replicate it with a simple example so I know something odd must be going on!!! Basically it's...
4
3127
by: Jim Langston | last post by:
This should illistrate what I am trying to do: template <class T> T SomeFunction( T parm ) { return parm; } template <class T> class SomeClass
2
2912
by: domehead100 | last post by:
I have a templated class, CDerived: template <typename TValue, typename TDraw, typename TEdit ...> class CDerived : public CBase { TValue m_Value public: TValue& GetValue() const {
2
2272
card
by: card | last post by:
Hi everyone, I have a question about referencing a nested class contained within a templated class. Of course the best way to show you is by example. Here's my templated classes: #include...
0
7201
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7083
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
7278
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,...
1
6988
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
4672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3166
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1510
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
734
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
379
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.