Template template partial specialization

H

Hizo

Hi everybody,

I would like to use partial template specialization with template
parameters and optional template parameters, but I didn't find out
documentation about it and my compiler (g++) doesn't seem to accept
it : so how to proceed ?

For a piece of illustration here is my situation:
---------------------------------
// global
template< template <class> class, class >
class Z
{};

// e.g.
template< class, class Opt = O >
class X
{};

// specialized
template< class B, class Opt = O >
class Z< X<class, O>, B >
{};
 
V

Victor Bazarov

Hi everybody,

I would like to use partial template specialization with template
parameters and optional template parameters, but I didn't find out
documentation about it and my compiler (g++) doesn't seem to accept
it : so how to proceed ?

For a piece of illustration here is my situation:

Don't post "a piece". Post a complete program you're trying to compile.
Don't post a huge one, remove everything irrelevant to your inquiry.
FAQ 5.8.
---------------------------------
// global
template< template<class> class, class>
class Z
{};

// e.g.
template< class, class Opt = O>

What's "O"?
class X
{};

// specialized
template< class B, class Opt = O>

Again, what's "O"?
class Z< X<class, O>, B>
{};

Sorry, can't provide any - not enough information in your article.

FAQ 5.8.

V
 
E

exhumea

Don't post "a piece".  Post a complete program you're trying to compile..
  Don't post a huge one, remove everything irrelevant to your inquiry.
FAQ 5.8.



What's "O"?



Again, what's "O"?



Sorry, can't provide any - not enough information in your article.

FAQ 5.8.

V

Ok, sorry I thought that it would help since it might be more clear.
Here is my come in substance in which I removed everything
irrelevant :
------------------------------------
#include <functional>
using std::equal_to;
using std::less_equal;

// a class
template< class T >
class Object
{
public:
Object(AType a, T t) : /* init members */ {}

/* class code */
};

// abstract class (designated as an interface for a relation order
between vectors)
template< class >
class VectorWeakOrder
{
/* code */
};

// template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class)
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}
};

// template SpecialOrder class which is a VectorWeakOrder of type T
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */
};

// partially specializing class ?
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
SpecialOrder< ValueType, Equal, LessOrEqual > special_order_obj;

/* do some stuff with order_obj and the class members (const) */

return ObjT( a, special_order_obj );
}
};
--------------------------------------
 
H

Hizo

Don't post "a piece". Post a complete program you're trying to compile.
Don't post a huge one, remove everything irrelevant to your inquiry.
FAQ 5.8.



What's "O"?



Again, what's "O"?



Sorry, can't provide any - not enough information in your article.

FAQ 5.8.

V

Ok, sorry I thought that it would help since it might be more clear.
Here is my come in substance in which I removed everything
irrelevant :
------------------------------------
#include <functional>
using std::equal_to;
using std::less_equal;

// a class
template< class T >
class Object
{
public:
Object(AType a, T t) : /* init members */ {}

/* class code */
};

// abstract class (designated as an interface for a relation order
between vectors)
template< class >
class VectorWeakOrder
{
/* code */
};

// template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class)
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}
};

// template SpecialOrder class which is a VectorWeakOrder of type T
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */
};

// partially specializing class ?
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
SpecialOrder< ValueType, Equal, LessOrEqual > special_order_obj;

/* do some stuff with order_obj and the class members (const) */

return ObjT( a, special_order_obj );
}
};
--------------------------------------
 
H

Hizo

Don't post "a piece". Post a complete program you're trying to compile.
Don't post a huge one, remove everything irrelevant to your inquiry.
FAQ 5.8.



What's "O"?



Again, what's "O"?



Sorry, can't provide any - not enough information in your article.

FAQ 5.8.

V

Ok, sorry I thought that it would help since it might be more clear.
Here is my code in substance in which I removed everything
irrelevant :
------------------------------------
#include <functional>
using std::equal_to;
using std::less_equal;

// a class
template< class T >
class Object
{
public:
Object(AType a, T t) : /* init members */ {}

/* class code */
};

// abstract class (designated as an interface for a relation order
between vectors)
template< class >
class VectorWeakOrder
{
/* code */
};

// template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class)
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}
};

// template SpecialOrder class which is a VectorWeakOrder of type T
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */
};

// partially specializing class ?
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
SpecialOrder< ValueType, Equal, LessOrEqual > special_order_obj;

/* do some stuff with order_obj and the class members (const) */

return ObjT( a, special_order_obj );
}
};
--------------------------------------
 
V

Victor Bazarov

Ok, sorry I thought that it would help since it might be more clear.
Here is my code in substance in which I removed everything
irrelevant :

I took your code and tried compiling it. Lots of irrelevant errors still.

Please, read the FAQ 5.8. If you're asking about a compile error, you
are going to get the most help if you supply the example that produces
your error, and only your error. For instance, in your code you have

// a class
template< class T >
class Object
{
public:
Object(AType a, T t) : /* init members */ {}
/* class code */
};

'AType' in undefined. You need to define it, even if you just make it a
typedef'ed int. The colon that does not have anything after that needs
to be removed as well before you post your question here. Make all
comments C-style: /*like this*/.

I am not trying to be difficult. I am trying to help you post the right
amount of relevant information. Read the FAQ please.

As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"? It might help you immensely. There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web. Have you tried googling for them?

V
 
I

itaj sherman

Hi everybody,

I would like to use partial template specialization with template
parameters and optional template parameters, but I didn't find out
documentation about it and my compiler (g++) doesn't seem to accept
it : so how to proceed ?

For a piece of illustration here is my situation:
---------------------------------
// global
template< template <class> class, class >
class Z
{};

// e.g.
template< class, class Opt = O >
class X
{};

// specialized
template< class B, class Opt = O >
class Z< X<class, O>, B >
{};

Didn't you mean "X<class, Opt >"?

I think you can do:

template< class B, class T, class Opt = O >
class Z< X< T, Opt >, B >
{};

itaj
 
H

Hizo

Didn't you mean "X<class, Opt >"?

I think you can do:

template< class B, class T, class Opt = O >
class Z< X< T, Opt >, B >
{};

itaj

template< class B, class T, class Opt = O >
class Z< X< T, Opt >, B >
{};

does not work:
* type/value mismatch at argument 1 in template parameter list for
‘template<template<class> class<template-parameter-1-1>, class> class
Z’
* expected a class template, got ‘X<T, Opt>’

I also tried :

template < class Opt >
class R
{
public:
template< class T >
class W: X<T, Opt>
{};
};

template< class B, class Opt = O >
class Z< R<Opt>::W, B >
{};

but it's not better.
(even if:
-------------
class K;

template< class B >
class Z< R<K>::W, B >
{};
 
H

Hizo

I took your code and tried compiling it.  Lots of irrelevant errors still.

Please, read the FAQ 5.8.  If you're asking about a compile error, you
are going to get the most help if you supply the example that produces
your error, and only your error.  For instance, in your code you have

    // a class
    template< class T >
    class Object
    {
      public:
         Object(AType a, T t) : /* init members */ {}
      /* class code */
    };

'AType' in undefined.  You need to define it, even if you just make it a
typedef'ed int.  The colon that does not have anything after that needs
to be removed as well before you post your question here.  Make all
comments C-style: /*like this*/.

Here it is :
-----------------------
#include <functional>
using std::equal_to;
using std::less_equal;

typedef int AType;

/* a class */
template< class T >
class Object
{
public:
Object(AType a, T t)
{
/* init */
}

/* class code */
};

/* abstract class (designated as an interface for a relation order
between vectors) */
template< class >
class VectorWeakOrder
{
/* code */
};

/* template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class) */
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
AType a;

/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}
};

/* template SpecialOrder class which is a VectorWeakOrder of type T */
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */
};

/* partially specializing class ? */
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
AType a;
SpecialOrder< ValueType, Equal, LessOrEqual > special_order_obj;

/* do some stuff with order_obj and the class members (const) */

return ObjT( a, special_order_obj );
}
};
-------------------------------------
As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"?  It might help you immensely.  There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web.  Have you tried googling for them?

No I have not, but that's why I thought I could find help here.
However I searched around in the web but I didn't find out examples of
template template parameter partial specialization, or the partial
specialization wasn't on the template template parameter but on other
parameters.

Thanks for your time.
 
H

Hizo

I took your code and tried compiling it.  Lots of irrelevant errors still.

Please, read the FAQ 5.8.  If you're asking about a compile error, you
are going to get the most help if you supply the example that produces
your error, and only your error.  For instance, in your code you have

    // a class
    template< class T >
    class Object
    {
      public:
         Object(AType a, T t) : /* init members */ {}
      /* class code */
    };

'AType' in undefined.  You need to define it, even if you just make it a
typedef'ed int.  The colon that does not have anything after that needs
to be removed as well before you post your question here.  Make all
comments C-style: /*like this*/.

I am not trying to be difficult.  I am trying to help you post the right
amount of relevant information.  Read the FAQ please.

As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"?  It might help you immensely.  There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web.  Have you tried googling for them?

V

Here it is :
-----------------------
#include <functional>
using std::equal_to;
using std::less_equal;

typedef int AType;

/* a class */
template< class T >
class Object
{
public:
Object(AType a, T t)
{
/* init */
}

/* class code */

};

/* abstract class (designated as an interface for a relation order
between vectors) */
template< class >
class VectorWeakOrder
{
/* code */

};

/* template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class) */
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
AType a;

/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}

};

/* template SpecialOrder class which is a VectorWeakOrder of type T */
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */

};

/* partially specializing class ? */
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only
a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
AType a;
SpecialOrder< ValueType, Equal, LessOrEqual >
special_order_obj;

/* do some stuff with order_obj and the class members
(const) */

return ObjT( a, special_order_obj );
}
};

-------------------------------------

* Arch: i686
* Kernel: Linux 2.6.32-hardened-r9-srv
* Compiler: gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5)
* Compiler flags: -O2 -march=i686 -mtune=prescott -pipe
* Error messages:
- error: type/value mismatch at argument 1 in template parameter list
for ‘template<template<class> class VectorWeakOrderT, class ValueType,
class Equal> class ROR’
- error: expected a class template, got ‘SpecialOrder<T, Equal,
LessOrEqual>’
As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"? It might help you immensely. There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web. Have you tried googling for them?

No I have not, but that's why I thought I could find help here.
However I searched around in the web but I didn't find out examples of
template template parameter partial specialization, or the partial
specialization wasn't on the template template parameter but on other
parameters.

Thanks for your time.
 
H

Hizo

Victor Bazarov a écrit :
I took your code and tried compiling it. Lots of irrelevant errors still..

Please, read the FAQ 5.8. If you're asking about a compile error, you
are going to get the most help if you supply the example that produces
your error, and only your error. For instance, in your code you have

// a class
template< class T >
class Object
{
public:
Object(AType a, T t) : /* init members */ {}
/* class code */
};

'AType' in undefined. You need to define it, even if you just make it a
typedef'ed int. The colon that does not have anything after that needs
to be removed as well before you post your question here. Make all
comments C-style: /*like this*/.

I am not trying to be difficult. I am trying to help you post the right
amount of relevant information. Read the FAQ please.

As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"? It might help you immensely. There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web. Have you tried googling for them?

V

Here it is :
-----------------------
#include <functional>
using std::equal_to;
using std::less_equal;

typedef int AType;

/* a class */
template< class T >
class Object
{
public:
Object(AType a, T t)
{
/* init */
}

/* class code */

};

/* abstract class (designated as an interface for a relation order
between vectors) */
template< class >
class VectorWeakOrder
{
/* code */

};

/* template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class) */
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
AType a;

/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}

};

/* template SpecialOrder class which is a VectorWeakOrder of type T */
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */

};

/* partially specializing class ? */
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
/* same code as before (before I was trying to specialize only
a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

/* specialized method */
ObjT create() const
{
AType a;
SpecialOrder< ValueType, Equal, LessOrEqual >
special_order_obj;

/* do some stuff with special_order_obj and the class
members
(const) */

return ObjT( a, special_order_obj );
}

};

-------------------------------------

* Arch: i686
* Kernel: Linux 2.6.32-hardened-r9-srv
* Compiler: gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5)
* Compiler flags: -O2 -march=i686 -mtune=prescott -pipe -g -Wall
* Error messages:
- error: type/value mismatch at argument 1 in template
parameter list
for ‘template<template<class> class VectorWeakOrderT, class ValueType,
class Equal> class ROR’
- error: expected a class template, got ‘SpecialOrder<T,
Equal,
LessOrEqual>’
As for partial specializations, do you have a copy of Vandevoorde and
Josuttis, "C++ Templates"? It might help you immensely. There are
probably numerous examples of specializations you can already find in
previous posts, and generally on the Web. Have you tried googling for them?

No I have not, but that's why I thought I could find help here.
However I searched around in the web but I didn't find out examples of
template template parameter partial specialization, or the partial
specialization wasn't on the template template parameter but on other
parameters.

Thanks for your time.
 
V

Victor Bazarov

Here it is :
-----------------------
#include<functional>
using std::equal_to;
using std::less_equal;

typedef int AType;

/* a class */
template< class T>
class Object
{
public:
Object(AType a, T t)
{
/* init */
}

/* class code */
};

/* abstract class (designated as an interface for a relation order
between vectors) */
template< class>
class VectorWeakOrder
{
/* code */
};

/* template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class) */
template< template<class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType> >
class ROR
{
/* code */

typedef Object< VectorWeakOrderT<ValueType> > ObjT;

ObjT create() const
{
AType a;

/* code */

return ObjT( a, VectorWeakOrderT<ValueType>() );
}
};

/* template SpecialOrder class which is a VectorWeakOrder of type T */
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
/* class code */
};

/* partially specializing class ? */
template< class ValueType, class Equal = equal_to< ValueType>, class
LessOrEqual = less_equal< ValueType> >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal>

I'm still unclear (a) why you think you need this and (b) how you'd use
that class template ROR. If the first argument of this template is
unused in the case of the specialization, then why do you need it to be
specific?

I have a sneaky suspicion, that you need a particular 'create' member
for all 'ROR' that have SpecialOrder with specific second and third
argument as its first argument, but I have hard time convincing myself
that there is no other solution...
{
/* same code as before (before I was trying to specialize only a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

Does it have to be a method of the class? Couldn't it be a stand-alone
function? You could always use overloading (since there is no partial
specializing of function templates)...
/* specialized method */
ObjT create() const
{
AType a;
SpecialOrder< ValueType, Equal, LessOrEqual> special_order_obj;

Since you're using a full specialization here, the only reason to go
into all this trouble is because you need to supply something as the
first argument for this template class partial specialization, yes?
/* do some stuff with order_obj and the class members (const) */

return ObjT( a, special_order_obj );
}
};

We will provide as much help as we can, but a newsgroup advice is by no
means a replacement for proper studying with a proper book.
However I searched around in the web but I didn't find out examples of
template template parameter partial specialization, or the partial
specialization wasn't on the template template parameter but on other
parameters.

Thanks for your time.

V
 
G

Gil

Victor Bazarov a écrit :













Here it is :
-----------------------
#include <functional>
using std::equal_to;
using std::less_equal;

typedef int AType;

/* a class */
template< class T >
class Object
{
        public:
                Object(AType a, T t)
                {
                        /* init */
                }

        /* class code */

};

/* abstract class (designated as an interface for a relation order
between vectors) */
template< class >
class VectorWeakOrder
{
        /* code */

};

/* template class (no polymorphism but template because we must create
pointer of that type order for further use of special properties of it
in one of the methods of this class) */
template< template <class> class VectorWeakOrderT, class ValueType,
class Equal = equal_to< ValueType > >
class ROR
{
        /* code */

        typedef Object< VectorWeakOrderT<ValueType> > ObjT;

        ObjT create() const
        {
                AType a;

                /* code */

                return ObjT( a, VectorWeakOrderT<ValueType>() );
        }

};

/* template SpecialOrder class which is a VectorWeakOrder of type T */
template< class T, class Equal = equal_to<T>, class LessOrEqual =
less_equal<T> >
class SpecialOrder: VectorWeakOrder<T>
{
        /* class code */

};

/* partially specializing class ? */
template< class ValueType, class Equal = equal_to< ValueType >, class
LessOrEqual = less_equal< ValueType > >
class ROR< SpecialOrder<class T,Equal,LessOrEqual>, ValueType, Equal >
{
        /* same code as before (before I was trying to specializeonly
a
templated method of the unspecialized template class but I read that
it was not standard so I gave up this idea and specialized the entire
class which was templated with another argument which is only useful
for this method) */

        /* specialized method  */
        ObjT create() const
        {
                AType a;
                SpecialOrder< ValueType, Equal, LessOrEqual >
special_order_obj;

                /* do some stuff with special_order_obj and the class
members
(const) */

                return ObjT( a, special_order_obj );
        }

};

-------------------------------------

* Arch: i686
* Kernel: Linux 2.6.32-hardened-r9-srv
* Compiler: gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5)
* Compiler flags: -O2 -march=i686 -mtune=prescott -pipe -g -Wall
* Error messages:
        - error: type/value mismatch at argument 1 in template
parameter list
for ‘template<template<class> class VectorWeakOrderT, class ValueType,
class Equal> class ROR’
        - error:    expected a class template, got ‘SpecialOrder<T,
Equal,
LessOrEqual>’


No I have not, but that's why I thought I could find help here.
However I searched around in the web but I didn't find out examples of
template template parameter partial specialization, or the partial
specialization wasn't on the template template parameter but on other
parameters.

Thanks for your time.- Hide quoted text -

- Show quoted text -

compiler message is right on: you passed a type instead of a template.
you were also trying to use an incompatible type when you tried to
specialize your ROR class:
inheritance didn't help when matching the template template argument
with the corresponding parameter.

I believe I understand your confusion;
your expectations were that argument:

SpecialOrder< class T, Equal, LessOrEqual >

would match the parameter:

template <class> class VectorWeakOrderT

in the primary template declaration.

but it doesn't.

beside being a type and not a template (your compiler error) there is
a template parameter type mismatch.

here is what I believe you can use:

//--------------------------------------------

template< class, class, class >
class VectorWeakOrder { /* code */ };

//primary template
template<
class ValueType,
class Equal = equal_to< ValueType >,
class LessEqual = less_equal< ValueType >,
template <
class = ValueType,
class = Equal,
class = LessEqual
class VectorWeakOrderT = VectorWeakOrder
class ROR{ /* code * };

template<
class ValueType,
class SpecialOrder
: VectorWeakOrder< ValueType, Equal, LessEqual >
{ /* class code */ };

//finally, specialize ROR on different Container&Order
template< class ValueType >
class ROR<
ValueType,
equal_to< ValueType >,
less_equal said:
{ /* class code * };

//--------------------------------------------

note: I kept your design to simplify the explanation;
but anyone that writes generic code for a living would actually expose
a helper policy that encapsulates both container and weak order binary
predicates:

template<
class ValueType,
class TOR {
};

hth,
gil
 
I

itaj sherman

Hi everybody,

I would like to use partial template specialization with template
parameters and optional template parameters, but I didn't find out
documentation about it and my compiler (g++) doesn't seem to accept
it : so how to proceed ?

For a piece of illustration here is my situation:
---------------------------------
// global
template< template <class> class, class >
class Z
{};

// e.g.
template< class, class Opt = O >
class X
{};

// specialized
template< class B, class Opt = O >
class Z< X<class, O>, B >
{};

OK, your question kept me thinking. My first reply was wrong, I didn't
clearly understood that the first parameter of Z (on which the
specialization is done) is a template class and not a class.
I think strictly speaking, in order to specialize on a template class,
like the first parameter of Z, you need the given argument to be such
a template class with one parameter. Your original definition of X
cannot be that, because it is just a template with 2 parameters and
there's no standard syntax in c++ to convolute it into what needed.

Also, to refine your question: suppose there was some way to define
such a partial specialization of Z, how would one ever use it? What
syntax is there to intanciate Z that would ever use that
specialization? There isn't any in standard c++.
You'd think something like: Z< X< ???, U >, B > could do that?

For example the following hipothetical syntax could do solve this. It
needs to support definitions of template of a template of a class.
Instead of X which is a 'template of a class', it would enable to
define X2 a 'template of a template of a class'.
* I think the default value given to the parameters doesn't affect
this problem anyway, so I'll just ommit that.

instead:
template< class T, class U > class X {...};

do:
template< class U > template< class T > class X2 {...};

or use X to define X2:
template< class U > template< class T > using X2 = X< T, U >;

in either case X2< U > is a 'template of a class'.
now X2 can be used to achieve the purpose (X can't do that directly at
all).

Z will be defined:
template< template< class > TT, class U >
class Z {};

and your required specialization defined:
template< class B, class U >
class Z< X2< U >, B > {};

an instanciation of Z that would use this specialization would be:
class D {};
class E {};
typedef Z< X2< D >, E > MyType;
//as said X2<D> is a template class with 1 parameter.

However AFAIK nothing like that is supported in the language.

I think there could be a workaround along the following guidelines.
This workaround requires some general library to handle "template-
functors". Below I give an implementation of two templates in such a
library that are needed for this example (TemplateFunctor1,
TemplateFunctor2, TemplateFunctorBind2).
I define a "template-functor" as a class that represents a template
class. It has a public template member "Instanciate" that can be
directly instanciated to give the represented template.
When defining Z and its partial specializations, the first parameter
of Z must be such a "template-functor" instead of an actual template.
Inside Z (and its specializations) one should use the "Instanciate"
member template of the given template-functor parameter.

class Z< class TF, class B >
{
//TF is a template-functor to achieve the actual template meant:
private: template< class T > TT = typename TF::Instanciate< T >;

//here use TT< ? > instead the original required parameter
}

if for example one would want to use Z with the following Y and E:
template< class T > class Y {};
class E {};
instead:
typedef Z< Y, E > MyType;
they have to use a template-functor that represent Y:
typedef Z< TemplateFunctor1< Y >, E > MyType;

and your problematic specialization:

template< class B, class Opt >
class Z< TemplateFunctorBind2< TemplateFunctor2< X >, Opt >, B >
{
private: template< class T > TT = X< T, Opt >;

//here use TT< ? > or directly X< T, Opt > where needed.
};

Then an instanciation like the following will use that specialization:
class D {};
class E {};
typedef Z< TemplateFunctorBind2< TemplateFunctor2< X >, D >, E >
MyType;

note the similarity of this with the above hipothetical syntax.

following are the templates from the suggested "template-functor
library" that were used above:

template< template< class > class TT > class TemplateFunctor1
{
public: template< class P > using Instanciate = typename TT< P1 >;
};

template< template< class, class > class TT > class TemplateFunctor2
{
public: template< class P1, class P2 > using Instanciate = typename
TT< P1, P2 >;
};

template< class Functor, class P2 >
class Bind2
{
public: template< class P1 > using Instanciate = typename
Functor::template Instanciate< P1, P2 >;
};

itaj
 
I

itaj sherman

Then an instanciation like the following will use that specialization:
class D {};
class E {};
typedef Z< TemplateFunctorBind2< TemplateFunctor2< X >, D >, E >
MyType;

note the similarity of this with the above hipothetical syntax.

To clearly explain why it is similar:

template< class U > template< class T > using X2 = X< T, U >;
typedef Z< X2< D >, E > MyType;

typedef TemplateFunctor2< X > X2;
typedef Z< TemplateFunctorBind2< X2, D >, E > MyType;

itaj
 
I

itaj sherman

does not work:
* type/value mismatch at argument 1 in template parameter list for
‘template<template<class> class<template-parameter-1-1>, class> class
Z’
* expected a class template, got ‘X<T, Opt>’

yeah ofcourse, I wasn't paying close attention.
I also tried :

template < class Opt >
class R
{
public:
template< class T >
class W: X<T, Opt>
{};

};

template< class B, class Opt = O >
class Z< R<Opt>::W, B >
{};

but it's not better.
(even if:
-------------
class K;

template< class B >
class Z< R<K>::W, B >
{};

that wouldn't work, and neither would my first thought was to suggest:
* although if you are willing to try a work-around with changing the
way this specialization is defined, I think you could use the
suggestion from my other post.

template < class Opt >
class R
{
public: template< class T >
class W
{
public: typedef X<T, Opt> type;
}
};

// global
template< class TT, class >
class Z
{
//use TT<?>::type
};

// specialized
template< class B, class Opt = O >
class Z< R<Opt>::W, B >
{
// use R<Opt>::W<?>::type
};

which would be better, but still the following doesn't work:

class K;
template< class B >
class Z< R<K>::W, B >
{};

Because it's not possible for the compiler to apply the template
parameter deduction on the left side of a qualified-id ":: operator"
in R<K>::W. I think for good reasons it's not possible.

The standard is not extremely clear about it, I think one has to go
through the template class specialization section, which in many
places redirects to the template function specialization section.
Specifically here 14.5.5.1/2 redirects to 14.8.2.
Where you can find 14.8.2.5/5:
"The non-deduced contexts are: — The nested-name-specifier of a type
that was specified using a qualified-id. ..."
from draft version 3225.

itaj
 
I

itaj sherman

following are the templates from the suggested "template-functor
library" that were used above:

template< template< class > class TT > class TemplateFunctor1
{
public: template< class P > using Instanciate = typename TT< P1 >;

};

template< template< class, class > class TT > class TemplateFunctor2
{
public: template< class P1, class P2 > using Instanciate = typename
TT< P1, P2 >;

};

template< class Functor, class P2 >
class Bind2
{
public: template< class P1 > using Instanciate = typename
Functor::template Instanciate< P1, P2 >;

};

The templated "using =" might be a problem, then the following can be
done instead, and used as X2::Instanciate< D, E >::type.

template< template< class > class TT > class TemplateFunctor1
{
public: template< class P > class Instanciate
{
public: typedef TT< P1 > type;
};
};


template< template< class, class > class TT > class TemplateFunctor2
{
public: template< class P1, class P2 > class Instanciate
{
public: typedef TT< P1, P2 > type;
};
};


template< class Functor, class P2 >
class Bind2
{
public: template< class P1 > class Instanciate
{
public: typedef Functor::template Instanciate< P1, P2 > type;
};
};

itaj
 
I

itaj sherman

template< class Functor, class P2 >
class Bind2
{
public: template< class P1 > class Instanciate
{
public: typedef Functor::template Instanciate< P1, P2 > type;
bah!

};

};

itaj
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top