473,226 Members | 1,718 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,226 software developers and data experts.

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 1744
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
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
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
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
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
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
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
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
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
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
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

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.