CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Static & Template sanity check.

    Can people just do a quick sanity check of this concept?
    I'm playing around with a technique to parameterise a template with the largest 'sizeof'
    result for a set of classes.

    A, B, C & D are classes with 1, 2, 3 & 4 members respectively.
    e is an instance of E, who's array member is sized according to the largest size of A, B, C or D.

    Can anyone think of a way that I may fall foul of the 'Static Initialisation Fiasco' with this setup?

    Code:
    //*********************************************************
    
    // MaxSizeOf for four parameters.
    template <const size_t S1,
              const size_t S2, 
              const size_t S3 = 0, 
              const size_t S4 = 0>
    struct MaxSizeOf
    {
        static const size_t MAX = MaxSizeOf<MaxSizeOf<S1, S2, S3>::MAX, S4>::MAX;
    };
    
    // MaxSizeOf for three parameters.
    template <const size_t S1, 
              const size_t S2, 
              const size_t S3>
    struct MaxSizeOf<S1, S2, S3>
    {
        static const size_t MAX = MaxSizeOf<MaxSizeOf<S1, S2>::MAX, S3>::MAX;
    };
    
    // MaxSizeOf for two parameters.
    template <const size_t S1, 
              const size_t S2>
    struct MaxSizeOf<S1, S2>
    {
        static const size_t MAX = (S1 > S2) ? S1 : S2;
    };
    
    //*********************************************************
    
    // Define an A.
    struct A
    {
        int i;
    };
    
    // Define a B.
    struct B
    {
        int i;
        int j;
    };
    
    // Define a C.
    struct C
    {
        int i;
        int j;
        int k;
    };
    
    // Define a D.
    struct D
    {
        int i;
        int j;
        int k;
        int l;
    };
    
    // Define a templated E.
    template <const size_t SIZE>
    struct E
    {
        char a[SIZE];
    };
    
    //*********************************************************
    
    // Declare an instance of an E.
    E<MaxSizeOf<sizeof(A), sizeof(B), sizeof(C), sizeof(D)>::MAX> e;
    
    //*********************************************************
    
    int main()
    {
        size_t size = sizeof(e.a);
    
        return 0;
    }
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Static & Template sanity check.

    Quote Originally Posted by JohnW@Wessex View Post
    Can anyone think of a way that I may fall foul of the 'Static Initialisation Fiasco' with this setup?
    Since everything seems to be compile-time computed, I don't see where the static initialisation will come into play.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    That's what I thought, but I just got a bit paranoid about missing some dark corner case.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

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

    Re: Static & Template sanity check.

    seems... elaborate...

    why not just:
    Code:
    template <typename T1, typename T2=char, typename T3=char, typename T4=char> // Add as many T as you want (compiler allowing)
    union MaxSizeOf
    {
    	T1 t1;
    	T2 t2;
    	T3 t3;
    	T4 t4;
    };
    
    
    int main()
    {
        size_t size = sizeof( MaxSizeOf<A,B,C,D> );
    
        return 0;
    }

  5. #5
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    Quote Originally Posted by OReubens View Post
    seems... elaborate...

    why not just:
    Code:
    template <typename T1, typename T2=char, typename T3=char, typename T4=char> // Add as many T as you want (compiler allowing)
    union MaxSizeOf
    {
    	T1 t1;
    	T2 t2;
    	T3 t3;
    	T4 t4;
    };
    
    
    int main()
    {
        size_t size = sizeof( MaxSizeOf<A,B,C,D> );
    
        return 0;
    }
    As I've just discovered, this technique does not compile if any of the template parameters have copy constructors.

    On Visual Studio this gives error C2621
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Static & Template sanity check.

    Quote Originally Posted by JohnW@Wessex View Post
    As I've just discovered, this technique does not compile if any of the template parameters have copy constructors.
    A union cannot have members that have non-trivial copy constructors.

    Why not try this:
    http://www.boost.org/doc/libs/1_54_0...l/variant.html

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    Yes that would be simpler.
    The technique I used was from a more generic solution for templates with variable numbers of type parameters.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

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

    Re: Static & Template sanity check.

    C++11 has variadric templates. (=Templates with a variable number of templates)

    So you'd have something like
    template <typename T, ...>

    with the ... being however many parameters the consumer want there to be. Rather than the template designer determining how many parameters there can be.

  9. #9
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    I work with embedded projects and, unfortunately, the compilers aren't likely to have C++11 support for a while yet.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

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

    Re: Static & Template sanity check.

    even in pre-c++11, you don't need O(N) specializations (without resorting to union tricks):

    Code:
    template < bool B, typename T, typename V >
    struct conditional { typedef T type; };
    
    template < typename T, typename V >
    struct conditional< false, T, V > { typedef V type; };
    
    template < typename T1, typename T2 = void, typename T3 = void, typename T4 = void >
    struct biggest_of
    {
    	typedef typename biggest_of<T2,T3,T4>::type BiggestOfOthers;
    
    	typedef typename conditional< ( sizeof(T1) >= sizeof(BiggestOfOthers) ),
    		T1, BiggestOfOthers >::type type;
    };
    
    template < typename T1 >
    struct biggest_of< T1, void, void, void >
    {
    	typedef T1 type;
    };
    
    // char some_array[ sizeof( biggest_of<A,B,C>::type ) ];
    with a possible c++11 version being something like:

    Code:
    #include <type_traits>
    
    template < typename Head, typename... Tail >
    struct biggest_of
    {
    	using BiggestOfTail = typename biggest_of<Tail...>::type;
    
    	typedef typename std::conditional< ( sizeof(Head) >= sizeof(BiggestOfTail) ),
    		Head, BiggestOfTail >::type type;
    };
    
    template < typename Tail >
    struct biggest_of< Tail >
    {
    	typedef Tail type;
    };
    or if one is interested in the size only:

    Code:
    template< typename Head >
    constexpr std::size_t max_sizeof() { return sizeof(Head); }
    
    template< typename Head, typename Middle, typename... Tail >
    constexpr std::size_t max_sizeof() { return sizeof(Head) >= max_sizeof<Middle,Tail...>() ? sizeof(Head) : max_sizeof<Middle,Tail...>(); }
    
    // char some_array[ max_sizeof<A,B,C>() ];

  11. #11
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    Thanks
    I haven't delved much into TMP yet (It tends to give me a headache quite quickly) but I'll squirrel that information away for future reference.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  12. #12
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Static & Template sanity check.

    I ended up using Superbonzo's technique.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Tags for this Thread

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