CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 27 of 27
  1. #16
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: void* in a struct

    Quote 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


  2. #17
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Thumbs up Re: void* in a struct

    Quote 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).

  3. #18
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: void* in a struct

    Quote 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


  4. #19
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    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.

  5. #20
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    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


  6. #21
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    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


  7. #22
    Join Date
    May 2005
    Posts
    151

    Re: void* in a struct

    Quote 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.

  8. #23
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    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).

  9. #24
    Join Date
    Sep 2003
    Location
    India
    Posts
    196

    Re: void* in a struct

    Quote 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
    Quote 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

  10. #25
    Join Date
    Feb 2004
    Location
    USA - Florida
    Posts
    729

    Re: void* in a struct

    Quote 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

  11. #26
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: void* in a struct

    Quote 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


  12. #27
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    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.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured