Correct use of 'typename...' to lazily match stl objects

Discussion in 'C++' started by m0shbear, May 4, 2011.

  1. m0shbear

    m0shbear Guest

    I'm using 'typename...' to preserve "extra" template arguments which
    have a default value so that I can do class partial specialization for
    identity purposes:

    namespace std { template <class T, typename... _> class vector; }
    namespace stxxl { template <class T, typename... _> class vector; }

    template <typename vc>
    struct ident {
    static bool has_bulk_iterator();
    };

    template <typename... _> struct ident<stxxl::vector<char, _> > {
    static bool has_bulk_iterator() {
    return false;
    }
    };

    template <typename... _> struct ident<std::vector<char, _> > {
    static bool has_bulk_iterator() {
    return true;
    }
    };

    However, typename... doesn't greedily gobble up _Alloc (for std) and
    [5 template args] (for stxxl), and <T,...> is incompatible with <T,
    _Alloc = ...<T>>.
    Is there a solution that allows implementation of match-and-ignore
    template spec'n as opposed to match-and-assume?
     
    m0shbear, May 4, 2011
    #1
    1. Advertising

  2. m0shbear

    Marc Guest

    m0shbear wrote:

    > I'm using 'typename...' to preserve "extra" template arguments which
    > have a default value so that I can do class partial specialization for
    > identity purposes:
    >
    > namespace std { template <class T, typename... _> class vector; }
    > namespace stxxl { template <class T, typename... _> class vector; }
    >
    > template <typename vc>
    > struct ident {
    > static bool has_bulk_iterator();
    > };
    >
    > template <typename... _> struct ident<stxxl::vector<char, _> > {


    _ is a pack, so you need "..." when you use it. vector<char,_...> maybe?
    (I haven't checked in detail what you are doing)
     
    Marc, May 4, 2011
    #2
    1. Advertising

  3. m0shbear

    m0shbear Guest

    On May 4, 9:24 am, Marc <> wrote:
    > m0shbear  wrote:
    > > I'm using 'typename...' to preserve "extra" template arguments which
    > > have a default value so that I can do class partial specialization for
    > > identity purposes:

    >
    > > namespace std { template <class T, typename... _> class vector; }
    > > namespace stxxl { template <class T, typename... _> class vector; }

    >
    > > template <typename vc>
    > > struct ident {
    > >         static bool has_bulk_iterator();
    > > };

    >
    > > template <typename... _> struct ident<stxxl::vector<char, _> > {

    >
    > _ is a pack, so you need "..." when you use it. vector<char,_...> maybe?
    > (I haven't checked in detail what you are doing)


    If I comment out the varargs definition of std::vector, stxxl::vector,
    then the only non-compiling left is:
    vec-ident.h:33: sorry, unimplemented: cannot expand ‘_ ...’ into a
    fixed-length argument list

    Seeing as it's going to be a few years until the compilers implement
    this, is there a functioning workaround, short of templating _all_ the
    args?
     
    m0shbear, May 4, 2011
    #3
  4. m0shbear

    Samkit Jain Guest

    On May 4, 7:49 pm, m0shbear <> wrote:
    > On May 4, 9:24 am, Marc <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > m0shbear  wrote:
    > > > I'm using 'typename...' to preserve "extra" template arguments which
    > > > have a default value so that I can do class partial specialization for
    > > > identity purposes:

    >
    > > > namespace std { template <class T, typename... _> class vector; }
    > > > namespace stxxl { template <class T, typename... _> class vector; }

    >
    > > > template <typename vc>
    > > > struct ident {
    > > >         static bool has_bulk_iterator();
    > > > };

    >
    > > > template <typename... _> struct ident<stxxl::vector<char, _> > {

    >
    > > _ is a pack, so you need "..." when you use it. vector<char,_...> maybe?
    > > (I haven't checked in detail what you are doing)

    >
    > If I comment out the varargs definition of std::vector, stxxl::vector,
    > then the only non-compiling left is:
    > vec-ident.h:33: sorry, unimplemented: cannot expand ‘_ ...’ into a
    > fixed-length argument list
    >
    > Seeing as it's going to be a few years until the compilers implement
    > this, is there a functioning workaround, short of templating _all_ the
    > args?


    How about this program? Is this something which you are trying to
    solve?

    #include <iostream>

    using namespace std;

    template <typename... args>
    class class_w_bulk_iterator
    {
    public:
    };

    template <typename... args>
    class class_wo_bulk_iterator
    {
    public:
    };

    template <template <typename...> class U>
    class has_bulk_iterator;

    template <>
    class has_bulk_iterator <class_wo_bulk_iterator>
    {
    public:
    enum
    {
    value = 0
    };
    };

    template <>
    class has_bulk_iterator <class_w_bulk_iterator>
    {
    public:
    enum
    {
    value = 1
    };
    };

    int main(int argc, const char *argv[])
    {
    cout << "class_w_bulk_iterator has bulk iterator = " <<
    has_bulk_iterator<class_w_bulk_iterator>::value << endl;
    cout << "class_wo_bulk_iterator has bulk iterator = " <<
    has_bulk_iterator<class_wo_bulk_iterator>::value << endl;
    return 0;
    }
     
    Samkit Jain, May 4, 2011
    #4
  5. m0shbear

    m0shbear Guest

    On May 4, 12:25 pm, Samkit Jain <> wrote:
    > On May 4, 7:49 pm, m0shbear <> wrote:
    >
    >
    >
    > > On May 4, 9:24 am, Marc <> wrote:

    >
    > > > m0shbear  wrote:
    > > > > I'm using 'typename...' to preserve "extra" template arguments which
    > > > > have a default value so that I can do class partial specialization for
    > > > > identity purposes:

    >
    > > > > namespace std { template <class T, typename... _> class vector; }
    > > > > namespace stxxl { template <class T, typename... _> class vector; }

    >
    > > > > template <typename vc>
    > > > > struct ident {
    > > > >         static bool has_bulk_iterator();
    > > > > };

    >
    > > > > template <typename... _> struct ident<stxxl::vector<char, _> > {

    >
    > > > _ is a pack, so you need "..." when you use it. vector<char,_...> maybe?
    > > > (I haven't checked in detail what you are doing)

    >
    > > If I comment out the varargs definition of std::vector, stxxl::vector,
    > > then the only non-compiling left is:
    > > vec-ident.h:33: sorry, unimplemented: cannot expand ‘_ ...’ into a
    > > fixed-length argument list

    >
    > > Seeing as it's going to be a few years until the compilers implement
    > > this, is there a functioning workaround, short of templating _all_ the
    > > args?

    >
    > How about this program? Is this something which you are trying to
    > solve?
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > template <typename... args>
    > class class_w_bulk_iterator
    > {
    > public:
    >
    > };
    >
    > template <typename... args>
    > class class_wo_bulk_iterator
    > {
    > public:
    >
    > };
    >
    > template <template <typename...> class U>
    > class has_bulk_iterator;
    >
    > template <>
    > class has_bulk_iterator <class_wo_bulk_iterator>
    > {
    > public:
    >     enum
    >     {
    >         value = 0
    >     };
    >
    > };
    >
    > template <>
    > class has_bulk_iterator <class_w_bulk_iterator>
    > {
    > public:
    >     enum
    >     {
    >         value = 1
    >     };
    >
    > };
    >
    > int main(int argc, const char *argv[])
    > {
    >     cout << "class_w_bulk_iterator has bulk iterator = " <<
    > has_bulk_iterator<class_w_bulk_iterator>::value << endl;
    >     cout << "class_wo_bulk_iterator has bulk iterator = " <<
    > has_bulk_iterator<class_wo_bulk_iterator>::value << endl;
    >     return 0;
    >
    > }
    >
    >


    Fails when you use class_w_bulk_iterator<T1 /*(, ..., Tn)/*>, because
    of instantiation. I need to match a class from an instance, and _...
    comes in very handy. Unfortunately, no compiler support any time soon.
    Hence, there is a need for functional workarounds.
     
    m0shbear, May 5, 2011
    #5
  6. m0shbear

    m0shbear Guest

    On May 4, 12:25 pm, Samkit Jain <> wrote:
    > On May 4, 7:49 pm, m0shbear <> wrote:
    >
    >
    >
    > > On May 4, 9:24 am, Marc <> wrote:

    >
    > > > m0shbear  wrote:
    > > > > I'm using 'typename...' to preserve "extra" template arguments which
    > > > > have a default value so that I can do class partial specialization for
    > > > > identity purposes:

    >
    > > > > namespace std { template <class T, typename... _> class vector; }
    > > > > namespace stxxl { template <class T, typename... _> class vector; }

    >
    > > > > template <typename vc>
    > > > > struct ident {
    > > > >         static bool has_bulk_iterator();
    > > > > };

    >
    > > > > template <typename... _> struct ident<stxxl::vector<char, _> > {

    >
    > > > _ is a pack, so you need "..." when you use it. vector<char,_...> maybe?
    > > > (I haven't checked in detail what you are doing)

    >
    > > If I comment out the varargs definition of std::vector, stxxl::vector,
    > > then the only non-compiling left is:
    > > vec-ident.h:33: sorry, unimplemented: cannot expand ‘_ ...’ into a
    > > fixed-length argument list

    >
    > > Seeing as it's going to be a few years until the compilers implement
    > > this, is there a functioning workaround, short of templating _all_ the
    > > args?

    >
    > How about this program? Is this something which you are trying to
    > solve?
    >
    > template <typename... args>
    > class class_w_bulk_iterator {}
    >
    > template <typename... args>
    > class class_wo_bulk_iterator {}
    >
    > template <typename U>
    > class has_bulk_iterator;
    >
    > template <>
    > struct has_bulk_iterator <class_wo_bulk_iterator>

    Matches the class
    template <typename... args>
    struct has_bulk_iterator<class_wo_bulk_iterator<args ...> >
    Matches arbitrary template-instances of the class

    I need the latter, but compilers don't support it. The former creates
    incorrect behavior.

    > {
    >   enum
    >   {
    >       value = 0
    >   };
    >
    > };
     
    m0shbear, May 5, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jakob Bieling

    Q: typename or not typename?

    Jakob Bieling, Mar 14, 2006, in forum: C++
    Replies:
    2
    Views:
    374
    Rolf Magnus
    Mar 14, 2006
  2. levy
    Replies:
    0
    Views:
    357
  3. méchoui
    Replies:
    8
    Views:
    348
    méchoui
    Aug 2, 2008
  4. Steve Hicks
    Replies:
    2
    Views:
    1,314
  5. Nathan Rice
    Replies:
    0
    Views:
    178
    Nathan Rice
    Jan 16, 2012
Loading...

Share This Page