Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8983245
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T20:47:37+00:00 2026-06-15T20:47:37+00:00

I’m using variadic templates with multiple virtual inheritance in C++ to aggregate types into

  • 0

I’m using variadic templates with multiple virtual inheritance in C++ to aggregate types into a single structure definition.

Here is a sample set of structures:

struct meas { int i; };
struct meas2 : public virtual meas { int j; };
struct meas3 : public virtual meas { int k; };

I then aggregate these using multiple virtual inheritance:

template <typename... Args>
struct zipper : public virtual Args... {};

I can then do:

typedef zipper<meas, meas2> meas_type;
meas* m = new meas_type;

These can then cascade:

typedef zipper<meas3, meas_type> meas_type2;

The resulting object, however, is rather unwieldy:

$46 = (zipper<meas3, zipper<meas, meas2> >) {
  <meas3> = {
    <meas> = {
      i = 0
    }, 
    members of meas3: 
    _vptr.meas3 = 0x400ec8, 
    k = 0
  }, 
  <zipper<meas, meas2>> = {
    <meas2> = {
      members of meas2: 
      _vptr.meas2 = 0x400ee0, 
      j = 6299120
    }, 
    members of zipper<meas, meas2>: 
    _vptr.zipper = 0x400eb0
  }, <No data fields>}

according to gdb.

There is also a secondary problem when attempting to zip the same base type:

typedef zipper<meas, meas> meas_type2;

The above produces the compiler error “duplicate base class ‘meas’ is invalid” under G++ 4.6.3.

The question is thus twofold:

  1. Is there a way to transform zipper<meas3, zipper<meas, meas2>> into zipper<meas3, meas2>?
  2. Is there a way, while accomplishing #1, to remove duplicate entries in the type list?

Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T20:47:38+00:00Added an answer on June 15, 2026 at 8:47 pm

    My strategy for solving this problem is to use a few levels of indirection.

    • zipper < Args… > dispatches the treating of its arguments to a function process_zipper_arguments by inheriting:

    Example:

    template < typename... Args >
    struct zipper : zipper < typename process_zipper_arguments < Args... >::type > {};
    
    • use a template < typename... Args > struct typelist {} to keep track of the object types from which you want to inherit.
    • Specialize struct zipper < typelist < Args... > >: public virtual Args... to do the actual inheritance

    In order to get rid of duplicate parent types, two helper functions are used in process_zipper_arguments:

    • is_in < CandidateType, typelist< Args... > >::type is either true_type or false_type and can be defined recursively
    • add_unique < CandidateType, typelist< Args... > >::type is a typelist <...> that has either CandidateType added to it or not. It calls is_in to determine that.

    Here is the complete code that compiles at least with g++ (GCC) 4.6.3 with –std=c++0x. Criticism on it is welcome.

    // Forward declarations
    template < typename... Args >
    struct zipper;
    
    // Two types meaning true and false
    struct true_type {};
    struct false_type {};
    
    // The only purpose of this struct is to be associated with Types...
    template < typename... Types >
    struct typelist {};
    
    
    // ===================================================
    // is_in < type, typelist<...> >::type
    //     is true_type if type is in typelist
    //     is false_type if type is not in typelist
    
    // Assume TElement is not in the list unless proven otherwise
    template < typename TElement, typename TList >
    struct is_in {
      typedef false_type type;
    };
    
    // If it matches the first type, it is definitely in the list
    template < typename TElement, typename... TTail >
    struct is_in < TElement, typelist < TElement, TTail... > >
    {
      typedef true_type type;
    };
    
    // If it is not the first element, check the remaining list
    template < typename TElement, typename THead, typename... TTail >
    struct is_in < TElement, typelist < THead, TTail... > >
    {
      typedef typename is_in < TElement, typelist < TTail... > >::type type;
    };
    
    // ===================================================
    // add_unique < TNew, typelist<...> >::type
    //     is typelist < TNew, ... > if TNew is not already in the list
    //     is typelist <...> otherwise
    
    // Append a type to a type_list unless it already exists
    template < typename TNew, typename TList,
      typename Tis_duplicate = typename is_in < TNew, TList >::type
      >
    struct add_unique;
    
    // If TNew is in the list, return the list unmodified
    template < typename TNew, typename... TList >
    struct add_unique < TNew, typelist < TList... >, true_type >
    {
      typedef typelist < TList... > type;
    };
    
    // If TNew is not in the list, append it
    template < typename TNew, typename... TList >
    struct add_unique < TNew, typelist < TList... >, false_type >
    {
      typedef typelist < TNew, TList... > type;
    };
    
    // ===================================================
    // process_zipper_arguments < Args... >::type
    //     returns a typelist of types to be inherited from.
    //
    // It performs the following actions:
    // a) Unpack zipper<...> and typelist <...> arguments
    // b) Ignore values that are already in the list
    
    template < typename... Args >
    struct process_zipper_arguments;
    
    // Unpack a zipper in the first argument
    template < typename... ZipperArgs, typename... Args >
    struct process_zipper_arguments < zipper < ZipperArgs... >, Args... >
    {
      typedef typename process_zipper_arguments < ZipperArgs..., Args... >::type type;
    };
    
    // Unpack a typelist in the first argument
    template < typename... TypeListArgs, typename... Args >
    struct process_zipper_arguments < typelist < TypeListArgs... >, Args... >
    {
      typedef typename process_zipper_arguments < TypeListArgs..., Args... >::type type;
    };
    
    // End the recursion if the list is empty
    template < >
    struct process_zipper_arguments < >
    {
      typedef typelist < > type;
    };
    
    // Construct the list of unique types by appending them one by one
    template < typename THead, typename... TTail >
    struct process_zipper_arguments < THead, TTail... >
    {
      typedef typename
        add_unique < THead,
          typename process_zipper_arguments < TTail... >::type
        >::type type;
    };
    
    
    // ===================================================
    // The zipper class that you might want
    
    
    // If the list of types is not yet known, process it.
    // The inheritance is ugly, but there is a workaround
    template < typename... Args >
    struct zipper : zipper < typename process_zipper_arguments < Args... >::type >
    {
      // // Instead of inheriting, you can use zipper as a factory.
      // // So this:
      // typedef zipper < meas2, zipper < meas1, meas > > mymeas;
      // // Turns to:
      // typedef typename zipper < meas2, zipper < meas1, meas > >::type mymeas;
      typedef zipper < typename process_zipper_arguments < Args... >::type > type;
    };
    
    // If the list of types is known, inherit from each type
    template < typename... Args >
    struct zipper < typelist < Args... > >
    : public virtual Args...
    {};
    
    // ===================================================
    // Short usage demo, replace with your own code
    
    struct meas {
        int i;
    };
    
    struct meas2 {
        int j;
    };
    
    struct meas3 {
        int k;
    };
    
    
    typedef zipper < meas, meas, meas3 > meas_type;
    typedef zipper < meas2, meas_type, meas2 > meas_type2;
    
    typedef typename zipper < meas_type2 >::type nicer_meas_type2;
    
    
    int main ( int, char** )
    {
        meas * m = new meas_type2;
        meas_type2 n;
        nicer_meas_type2 o;
    
        return 0;
    }
    

    Debugging it gives the following result (breakpoint at the return 0; line):

    (gdb) print *m
    $1 = {i = 0}
    (gdb) print n
    $2 = {<zipper<typelist<meas, meas3, meas2> >> = {<meas> = {i = 4196320}, <meas3> = {k = 0}, <meas2> = {j = 0}, 
        _vptr.zipper = 0x400928}, <No data fields>}
    (gdb) print o
    $3 = {<meas> = {i = 4195719}, <meas3> = {k = 0}, <meas2> = {j = 1}, _vptr.zipper = 0x4009a8 <VTT for zipper<typelist<meas, meas3, meas2> >>}
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I am reading a book about Javascript and jQuery and using one of the
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I am currently running into a problem where an element is coming back from
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I have a French site that I want to parse, but am running into
We're building an app, our first using Rails 3, and we're having to build

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.