CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Template parameter resolving to 'nothing' ?

    I have a 'sort of' working solution for this, it's just way too elaborate to be very useful in a general sense...

    So.. Is there an "easy" way to define a template with a template parameter that could resolve to "nothing".

    Code:
    template <typename T1, typename T2, typename T3>
    struct one_to_three
    {
    public:
           T1 t1;
           T2 t2;
           T3 t3;
    };
    Now I want to be able to instantiate that in such a way that T3 and T2 (if T3 also) resolve to "nothing".

    Don't point me at tuple<>, this has to be a single structure
    No dummy's, nothing effectively means nothing.

    so on Win32
    Code:
    one_to_three <int, int, int> x;   
    sizeof(x) == 12;
    
    one_to_three <int, nothing, nothing> y;  // whatever 'nothing' needs to be.
    sizeof(y) == 4;
    T1 will never be 'nothing'
    T2 will only be 'nothing' if T3 also is 'nothing' (if it works with T3 not being nothing, that's fine, but it won't get used that way).
    portability is a non-issue, this only needs to work in VS (2010 and higher)

    the 'real' solution will need up to T10, I have a solution working with SFINAE, but it takes very very long to compile and it's getting very unwieldy if you would need to add T11.
    I know it's not an ideal type approach, but it is what it is, this is a necessity due to linking with a legacy API which we don't have control over.
    Last edited by OReubens; April 2nd, 2015 at 10:24 AM.

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Template parameter resolving to 'nothing' ?

    ... and why can't you specialize for "nothing" ?

    Code:
    struct nothing_t{};
    
    template<class T1,class T2> struct one_two_three<T1,T2,nothing_t> { .... };
    ...

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Template parameter resolving to 'nothing' ?

    to elaborate. if I define

    one_to_three<int, nothing, nothing> x;

    then it's ok if x.t2 and x.t3 are invalid.

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Template parameter resolving to 'nothing' ?

    Quote Originally Posted by superbonzo View Post
    ... and why can't you specialize for "nothing" ?

    Code:
    struct nothing_t{};
    
    template<class T1,class T2> struct one_two_three<T1,T2,nothing_t> { .... };
    ...
    because sizeof(nothing_t) == 1

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Template parameter resolving to 'nothing' ?

    nope, it's a specialization so in the "...." you can omit the nothing_t instance, unless for some reason you cannot specialize ...

  6. #6
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Template parameter resolving to 'nothing' ?

    Quote Originally Posted by superbonzo View Post
    nope, it's a specialization so in the "...." you can omit the nothing_t instance, unless for some reason you cannot specialize ...
    you mean... redefine the entire class for 2 members, and redefine it again for 1 member ?

    that's an even less than ideal solution than what I have now. The specific class code is now over 10000 lines. Making 10 variants would mean copying the same code 10x. for each specialization.

  7. #7
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Template parameter resolving to 'nothing' ?

    you said "T2 will only be 'nothing' if T3 also is 'nothing'" and I assumed, the same applies for T4,T5,... so, the specializations seemed to be just two in total ( <T1,T2,...> and <T1,nothing,nothing,...> ).

    anyway, even if each Tj can be "nothing" independently, there's no need of having Nx code duplication:

    Code:
    template < class U >
    struct impl
    {
    	void some_big_code() // of course, members using "nothing"ified members will give error if ( and only if ) invoked
    	{
    		do_something_with( static_cast<U*>(this)->t1 );
    		do_something_with( static_cast<U*>(this)->t2 );
    		...
    	}
    };
    
    template < class T1, class T2, class T3 >
    struct frontend:impl<frontend<T1,T2,T3>>
    {
    	T1 t1;
    	T2 t2;
    	T3 t3;
    }
    
    template < class T1 >
    struct frontend<T1,nothing,nothing>:impl<frontend<T1,nothing,nothing>>
    {
    	T1 t1;
    }
    
    // ...
    and if the number of combinations gets big ( and the preprocessor can't help ), one can use the empty base class optimization to write just one ( or O(N) in pre-c++11 ) frontend<> templates ...

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Template parameter resolving to 'nothing' ?

    Quote Originally Posted by superbonzo View Post
    you said "T2 will only be 'nothing' if T3 also is 'nothing'" and I assumed, the same applies for T4,T5,... so, the specializations seemed to be just two in total ( <T1,T2,...> and <T1,nothing,nothing,...> ).
    yes, it applies to T4 and T5 and T6...
    but not the other way around.
    just because T3 is 'nothing' doesn't mean T2 is nothing too
    but if T2 is nothing, then T3 will be nothing as well.

    or putting it otherwise, if TX is nothing, then all the next parameters are nothing also.

    Not entirely sure what your solution is about just yet (it'll dawn on me), but that static_cast there doesn't look very promising.
    Not the kind of "easy" I was hoping for

  9. #9
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Template parameter resolving to 'nothing' ?

    Quote Originally Posted by OReubens View Post
    Not entirely sure what your solution is about just yet (it'll dawn on me), but that static_cast there doesn't look very promising.
    Not the kind of "easy" I was hoping for
    it's just "standard" CRTP, it has the advantage of automatically "swithcing on and off" only the methods that the CRTP class wants ( with the exception of explicit instantiations );
    if the static_cast looks scary, one can put it inside an inline this_() method to make clear that it's THE CRTP forwarder... anyway, it's just a matter of style.
    Last edited by superbonzo; April 3rd, 2015 at 02:23 AM.

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Template parameter resolving to 'nothing' ?

    I realised it's CRTP. or rather, I did a few moments after my post
    It's definately a nifty approach.
    It's just a bit awkward/annoying you can't access the members easily in the impl class. Haven't had a chance to give this an actual go just yet (real life work has a nasty habbit of completely flipping you around every few days) to see if this'll cater to all the use cases well enough.

    I really was hopping to something akin to the VS __noop keyword to do the same for variables as it does for functions.
    A friend hinted me into yet another direction, but I've equally not had a chance to try that out just yet.

    So I have
    - the working yet unwieldy/getting_unmanageble SFINAE approach.
    - your CRTP approach with the nasty cast and indirect access to variables
    - the to be tried __if_exists/__if_not_exists approach my friend hinted at.

    To be continued . . .

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