|
-
June 17th, 2005, 06:06 AM
#16
Re: void* in a struct
 Originally Posted by exterminator
Is this the reason (in-lining) why you are not convinced if this can be space-efficient? Any other reasons?
I'm not convinced that templates are the horrible bloat-monsters that they get portrayed as. On the principle that you don't pay for what you don't use, then the mere existence of a template won't bloat code, and if you only use one function from a templated class, that's the only function that the compiler will expand from the template - which may be an improvement over writing separate versions of the class. On the assumption that if you're going to use the template, you would have written it longhand, anyway, I don't see how templates are worse than what you would have written. On the other hand, if you would have written something a bit less type-safe (so as to use one function where two or three would be better), then templates are encouraging you into better programming practices.
Anyway, this is all just gut feel and I have no data to back it up, but then I've seen no data to back up the code bloat theory, either (not that I've really looked).
As such, my preferred solution to the problem raised would be:
Code:
template <typename T>
struct myStruct
{
CString strVal;
T*vdptrVal;
};
actually, it would be:
Code:
template <typename T>
struct myStruct
{
std::string sensible_name_for_string_member;
T* sensible_name_for_pointer_member;
};
where you can substitute something appropriate for the "sensible" names. I might keep the CString if the struct was directly associated with MFC classes, otherwise, I'd use std::string and convert to CString as late as possible. Plus, I detest Hungarian warts on variable names.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
June 17th, 2005, 06:45 AM
#17
Re: void* in a struct
 Originally Posted by Graham
I'm not convinced that templates are the horrible bloat-monsters that they get portrayed as. On the principle that you don't pay for what you don't use, then the mere existence of a template won't bloat code, and if you only use one function from a templated class, that's the only function that the compiler will expand from the template - which may be an improvement over writing separate versions of the class. On the assumption that if you're going to use the template, you would have written it longhand, anyway, I don't see how templates are worse than what you would have written. On the other hand, if you would have written something a bit less type-safe (so as to use one function where two or three would be better), then templates are encouraging you into better programming practices.
I completely agree to this but you talked about the comparison between thin templates and (what i should i call) regular templates. I think you would agree upon the improvement though (caused by thin templates).
-
June 17th, 2005, 08:08 AM
#18
Re: void* in a struct
 Originally Posted by exterminator
I completely agree to this but you talked about the comparison between thin templates and (what i should i call) regular templates. I think you would agree upon the improvement though (caused by thin templates).
Not necessarily - and for much the same reasons I gave for regular templates over non-templates. Again, I've not done any studies on this - it's just a gut feeling, so could easily be wrong.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
June 17th, 2005, 08:23 AM
#19
Re: void* in a struct
My guess is that where a thin template might show an improvement is if you are going to have something like a collection of pointers, where you could create a vector (say) of void* pointers then cast them to the type the pointers really are, but to make the code typesafe, you instead are using templates.
Now, the question is what the compiler does. (In the real case of vector it doesn't have to be a vector of pointers, so we can assume here that the compiler has little choice).
If we have 20 different types and are going to use our vector< T* > on all 20 types calling the most common functions, is our compiler going to generate 20 different versions of vector or 1?
So that, I guess, is the basis behind a thin template (one set of generated code). Now I'm not sure exactly how you implement them.
-
June 17th, 2005, 09:27 AM
#20
Re: void* in a struct
Here's a (very) simplified example:
Code:
class arraybase
{
public:
// stuff
protected:
void* arr;
};
template <typename T>
class array : public arraybase
{
public:
T& operator[](int index)
{
return *(static_cast<T*>(arr) + index);
}
// more stuff
};
I still don't see how this is an improvement over moving the pointer into the templated class and making it a T*.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
June 17th, 2005, 09:29 AM
#21
Re: void* in a struct
And can I just say that I work with Symbian - I don't defend it. Needs must and all that; I don't have to like it particularly.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
June 17th, 2005, 11:24 AM
#22
Re: void* in a struct
 Originally Posted by NMTop40
If we have 20 different types and are going to use our vector< T* > on all 20 types calling the most common functions, is our compiler going to generate 20 different versions of vector or 1?
You'll get 20 different versions because the function signatures will be different for each type.
Code:
void vector<int*>::push_back( const int* &val );
void vector<char*>::push_back( const char* &val );
The compiler views those each as unique functions, even though the generated code may be identical given that a pointer is the same size regardless of its declared type. If it was vector<int> and vector<char>, then absolutely you would have multiple versions of the code because the size of each type is different.
The code bloat problem comes from the fact that templates are expanded inline. That means each compilation unit gets its own copy. So if you use those 20 different versions of vectors in 3 different source files, then you'll have a total of 60 copies of the code. That is the code bloat problem of templates. Or at least that's the way it used to be; newer compilers may be able to eliminate the duplicate code. I thought I saw that mentioned somewhere here on CodeGuru.
I've used the pattern shown by Graham above, where there is a non-template base class that performs as much type-independent processing as possible. Then a derived template class provides the code that is type-dependent. The intent is to minimize the amount of code that is duplicated as a result of template expansion.
For example, if all of the type-independent code can operate with void pointers, then most of the code would be in the base class and the template class would just provide methods to cast to/from the real data type, i.e. it would be very "thin". Maybe that's what the term "thin template" refers to? I don't know, I've never heard that term before.
-
June 18th, 2005, 07:22 PM
#23
Re: void* in a struct
Well I do work a lot with smart pointers, which always contain pointers, never objects, so they are generally the same size, and they do point to different types.
Perhaps I should try some experiment with thin templates, although where I work the code size is not a major issue (unlike on mobile phones where it is a much bigger issue).
-
June 19th, 2005, 08:35 PM
#24
Re: void* in a struct
 Originally Posted by Graham
As such, my preferred solution to the problem raised would be:
Code:
template <typename T>
struct myStruct
{
CString strVal;
T*vdptrVal;
};
actually, it would be:
Code:
template <typename T>
struct myStruct
{
std::string sensible_name_for_string_member;
T* sensible_name_for_pointer_member;
};
Sorry for the delayed response was not online all these days.. here in the above suggested case how do i use this struct template with vectors, like i want to use this vetor of this struct template.
like
Code:
vector<myStruct> vectStruct
 Originally Posted by Graham
I might keep the CString if the struct was directly associated with MFC classes, otherwise, I'd use std::string and convert to CString as late as possible. Plus, I detest Hungarian warts on variable names.
Yes i am associating this with MFC so i am using CString.
thanks for the suggestion
venky
-
June 19th, 2005, 10:49 PM
#25
Re: void* in a struct
 Originally Posted by santoct2002
Have you anytime heard about VARIANT type?? variant data type is used to extensively in COM programming. This may help you to hold different data type value. but It needs some considerable time to spend on this datatype to use your requirements, that I leave it to you. You can get more details in MSDN and in Codeguru also. Search for Variant.
Variant
There's also Boost Variant and Boost Any with included usage examples.
Hungarian notation, reinterpreted? http://www.joelonsoftware.com/articles/Wrong.html
-
June 20th, 2005, 03:40 AM
#26
Re: void* in a struct
 Originally Posted by venkyhyd
Sorry for the delayed response was not online all these days.. here in the above suggested case how do i use this struct template with vectors, like i want to use this vetor of this struct template.
like
Code:
vector<myStruct> vectStruct
Yes i am associating this with MFC so i am using CString.
thanks for the suggestion
venky 
Code:
vector<myStruct<myType> > vectstruct;
Note the space between the two '>' characters - this is very important.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
June 20th, 2005, 06:16 AM
#27
Re: void* in a struct
Variants are useful for when you have a collection of fields which may be of different types but you want to treat them as a whole. For example, a generic record of a database, which is a collection of fields of different types.
boost::any works with a common paradigm used in C++ (not sure if it has an official design pattern name) whereby you have a single base-class and from there you derive a template. (That pattern was used above). The base class has methods that are expected to have some meaning for any types that might be held, eg streaming.
This is a way to make all your classes derive from one common base class even when they don't.
I haven't looked at boost::variant in detail.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|