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

M

m0shbear

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?
 
M

Marc

m0shbear said:
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)
 
M

m0shbear

m0shbear  wrote:




_ 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?
 
S

Samkit Jain

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;
}
 
M

m0shbear

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

m0shbear

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top