473,898 Members | 2,061 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template partial specialization

Hi

Template partial specialization always seems like a fairly
straightforward concept - until I try to do it :).

I am trying to implement the input sequence type (from Stroustrup
section 18.3.1, 'Iseq'). I want the version for containers that he
gives, but also to provide a specialization for construction from a
pair<It,It> (eg because that is returned by equal_range()). [Iseq is
actually implemented as a pair<> - but that is a separate issue.]

Here is what I have:

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

// A type representing an 'input sequence':

template<class In>
class Iseq : public pair<In, In> {
public:
Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
bool IsEmpty() const { return first == second; }
};

// A helper function to make one (since ctors can't
// infer the types of template arguments):

template<class C>
Iseq<typename C::iterator> iseq(C& c) {
return Iseq<typename C::iterator>(c. begin(), c.end());
}

// A specialisation for pairs:

template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}

// An overloaded version of STL find() taking an input sequence:

template<class In, class T>
In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
}

// And finally, a client:

Iseq<MMIt> FindMemberships (UserReference member) {
return iseq_p( memberships_.eq ual_range(membe r) );
}
MMIt MemberAt(UserRe ference member, Path path) {
return find(FindMember ships(member), make_pair(membe r,
path));
}

// ---------------------------------------------------------------
This works. But only because I have renamed my 'specialisation ' of
iseq() for pairs to iseq_p. I don't want to (and don't think I have
to) do that, for this or any further specialisations . Simply replacing
'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
attempt to use the first definition of iseq, and it (rightly)
complains that pair<>::iterato r does not exist. What mistake am I
making?

[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
might be inclined to make it privately inherit it - surely no client
wants to use the pair<> interface? ]
Jul 19 '05 #1
17 6873


Paul MG wrote:
Hi

Template partial specialization always seems like a fairly
straightforward concept - until I try to do it :).

I am trying to implement the input sequence type (from Stroustrup
section 18.3.1, 'Iseq'). I want the version for containers that he
gives, but also to provide a specialization for construction from a
pair<It,It> (eg because that is returned by equal_range()). [Iseq is
actually implemented as a pair<> - but that is a separate issue.]

Here is what I have:

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

// A type representing an 'input sequence':

template<class In>
class Iseq : public pair<In, In> {
public:
Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
bool IsEmpty() const { return first == second; }
};

// A helper function to make one (since ctors can't
// infer the types of template arguments):

template<class C>
Iseq<typename C::iterator> iseq(C& c) {
return Iseq<typename C::iterator>(c. begin(), c.end());
}

// A specialisation for pairs:

template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}
this is not specialisation of class Iseq for pairs if u replace iseq_p
with Iseq. it is a function.
the specialisation is:

template <>
template <class T>
class Iseq<pair<T,T> >
{
public:
Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
};

this is not the solution to yr problem though, but it will give u the
basic idea.


// An overloaded version of STL find() taking an input sequence:

template<class In, class T>
In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
}

// And finally, a client:

Iseq<MMIt> FindMemberships (UserReference member) {
return iseq_p( memberships_.eq ual_range(membe r) );
}
MMIt MemberAt(UserRe ference member, Path path) {
return find(FindMember ships(member), make_pair(membe r,
path));
}

// ---------------------------------------------------------------
This works. But only because I have renamed my 'specialisation ' of
iseq() for pairs to iseq_p. I don't want to (and don't think I have
to) do that, for this or any further specialisations . Simply replacing
'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
attempt to use the first definition of iseq, and it (rightly)
complains that pair<>::iterato r does not exist. What mistake am I
making?

[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
might be inclined to make it privately inherit it - surely no client
wants to use the pair<> interface? ]


Jul 19 '05 #2


Paul MG wrote:
Hi

Template partial specialization always seems like a fairly
straightforward concept - until I try to do it :).

I am trying to implement the input sequence type (from Stroustrup
section 18.3.1, 'Iseq'). I want the version for containers that he
gives, but also to provide a specialization for construction from a
pair<It,It> (eg because that is returned by equal_range()). [Iseq is
actually implemented as a pair<> - but that is a separate issue.]

Here is what I have:

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

// A type representing an 'input sequence':

template<class In>
class Iseq : public pair<In, In> {
public:
Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
bool IsEmpty() const { return first == second; }
};

// A helper function to make one (since ctors can't
// infer the types of template arguments):

template<class C>
Iseq<typename C::iterator> iseq(C& c) {
return Iseq<typename C::iterator>(c. begin(), c.end());
}

// A specialisation for pairs:

template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}
this is not specialisation of class Iseq for pairs if u replace iseq_p
with Iseq. it is a function.
the specialisation is:

template <>
template <class T>
class Iseq<pair<T,T> >
{
public:
Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
};

this is not the solution to yr problem though, but it will give u the
basic idea.


// An overloaded version of STL find() taking an input sequence:

template<class In, class T>
In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
}

// And finally, a client:

Iseq<MMIt> FindMemberships (UserReference member) {
return iseq_p( memberships_.eq ual_range(membe r) );
}
MMIt MemberAt(UserRe ference member, Path path) {
return find(FindMember ships(member), make_pair(membe r,
path));
}

// ---------------------------------------------------------------
This works. But only because I have renamed my 'specialisation ' of
iseq() for pairs to iseq_p. I don't want to (and don't think I have
to) do that, for this or any further specialisations . Simply replacing
'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
attempt to use the first definition of iseq, and it (rightly)
complains that pair<>::iterato r does not exist. What mistake am I
making?

[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
might be inclined to make it privately inherit it - surely no client
wants to use the pair<> interface? ]


Jul 19 '05 #3
> > // A specialisation for pairs:

template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}


That isn't a specialization, but a function overload.


Hmmmm... so if you define a templated function

template<class T> iseq(T);

and then later add

template<> iseq(SomeType);

then the second is a function overload not a specialization? That is
what I am trying to do (I think). Its just that when SomeType is
'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
'template<>' like I have here...
Simply replacing
'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
attempt to use the first definition of iseq, and it (rightly)
complains that pair<>::iterato r does not exist. What mistake am I
making?


Using a 3 year old compiler. Upgrade to gcc 3.0+ and it will work
fine. The missing feature is "partial template function ordering",
which knows how to choose the best match amongst different template
specializations that match a function call.


I have other places in the code where it correctly chooses the 'most
specific' implementation of a templated function just like what I
outlined above. So I don't think it is total lack of compiler support
- it could be a failure to support something in this specific case I
suppose, yes.
[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
might be inclined to make it privately inherit it - surely no client
wants to use the pair<> interface? ]


Your find overload does...


Only cos I copied it out of Stroustrup. I would have preferred to
inherit Iseq<T> privately from pair<T,T>, and give it accessors
begin() and end() which return pair<T,T>::firs t and pair<T,T>::seco nd.

But I am unwilling to assume that I am cleverer than Stroustrup :).
Someone let me know my error?

cheers!

pmg
Jul 19 '05 #4
> > // A specialisation for pairs:

template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}
this is not specialisation of class Iseq for pairs if u replace iseq_p
with Iseq. it is a function.


['with iseq' is what I meant, I presume what you meant too]

i think what i was trying to do was create a specialisation of the
template function iseq, not the class Iseq (see my response to tom).
are you suggesting then that i am trying the wrong approach?
the specialisation is:

template <>
template <class T>
class Iseq<pair<T,T> >
{
public:
Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
};

this is not the solution to yr problem though, but it will give u the
basic idea.


Never seen that 'template<> template<class T>' thing before.
Interesting. So the 'template<>' shows that this is a partial
specialisation, the 'class Iseq<pair<T, T> >' says that it is a
specialisation for pairs, and the 'template <class T>' bit in between
states that pair<T,T> itself requires a template parameter T. Is that
right?

Anyway, now I can do this then:

pair<It, It> myRange = getRange();
find(ISeq(myRan ge), someValue);

?

Would rather specialise/overload the factory function iseq() than the
class itself though, if only because otherwise it is unsymmetrical
with the other case of constructing off a collection (which uses the
factory function so that the template type can be inferred):

vector<Foo> foos = getFoos();
find(iseq(foos) , someValue);
// which is just neater than:
// find(ISeq<Foo:: iterator>(foos) , someValue));

Hope this makes sense, thanks for your input,

cheers
pmg
Jul 19 '05 #5

Hmmmm... so if you define a templated function

template<class T> iseq(T);

and then later add

template<> iseq(SomeType);

then the second is a function overload not a specialization?
this is template function specialisation.
That is
what I am trying to do (I think). Its just that when SomeType is
'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
'template<>' like I have here...


yes, u shud write:

template<> template <typename T1, typename T2> iseq(pair<T1, T2>)
Jul 19 '05 #6

sorry...i messed up a bit....
what i meant is:
template <> is not partial specialization, it is fully specialisation :-))

Jul 19 '05 #7
On 25 Jun 2003 01:22:37 -0700, pa****@digitalb rain.com (Paul MG)
wrote:
> // A specialisation for pairs:
>
> template<class T>
> Iseq<T> iseq_p(pair<T, T> p) {
> return Iseq<T>(p.first , p.second);
> }
That isn't a specialization, but a function overload.


Hmmmm... so if you define a templated function

template<class T> iseq(T);

and then later add

template<> iseq(SomeType);

then the second is a function overload not a specialization?


It is a specialization (ignoring the missing return type). It is
better to write it as:

template<>
Iseq<WhateverTy pe> iseq<SomeType>( SomeType c);

so that the compiler knows with overload of iseq you are specializing
(by matching the bit between the <> with the signatures), if there is
more than one possibility (*).

The overload version would be:

Iseq<SomeType> iseq(SomeType);
That iswhat I am trying to do (I think). Its just that when SomeType is
'pair<T1,T2> ', you need to specify T1 and T2 too so you can't just say
'template<>' like I have here...
Ahh, so you are trying to partially specialize a function template.
That isn't possible in C++, so you have to use overloading. If partial
specialization existed, the syntax would be analogous to class partial
specialization:

template<class T>
Iseq<T> iseq<pair<T, T> >(pair<T, T> p) {
return Iseq<T>(p.first , p.second);
}

but if you feed that to your compiler, you'll get an error. In any
case, partial specialization wouldn't really make sense even if it did
exist, since you're changing the return type from T::iterator to, in
effect, T::first_type.

What you have is two completely different template functions that are
related only by the fact that they share the same name.
>Simply replacing
>'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
>attempt to use the first definition of iseq, and it (rightly)
>complains that pair<>::iterato r does not exist. What mistake am I
>making?
Using a 3 year old compiler. Upgrade to gcc 3.0+ and it will work
fine. The missing feature is "partial template function ordering",
which knows how to choose the best match amongst different template
specializations that match a function call.


I have other places in the code where it correctly chooses the 'most
specific' implementation of a templated function just like what I
outlined above. So I don't think it is total lack of compiler support
- it could be a failure to support something in this specific case I
suppose, yes.


I just tried it in g++, and it looks like the problem might be that
g++ doesn't properly implement SFINAE (substitution failure is not an
error), instead making the substitution of the pair into the first
overload an error, when all it should do is discard it from the
overload list.

So in fact, partial ordering doesn't directly affect this issue, since
the first overload should be eliminated before the compiler gets to
partial ordering.
>[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
>might be inclined to make it privately inherit it - surely no client
>wants to use the pair<> interface? ]


Your find overload does...


Only cos I copied it out of Stroustrup. I would have preferred to
inherit Iseq<T> privately from pair<T,T>, and give it accessors
begin() and end() which return pair<T,T>::firs t and pair<T,T>::seco nd.

But I am unwilling to assume that I am cleverer than Stroustrup :).
Someone let me know my error?


I suppose Iseq doesn't need accessors in the same way that pair
doesn't need them. It is a fundamental type that simply holds two
iterators.

However, adding accessors won't hurt anything except possibly
performance, depending on whether you return by value or reference.

Tom
Jul 19 '05 #8
On Wed, 25 Jun 2003 02:11:11 +0530, Chandra Shekhar Kumar
<ch***********@ oracle.com> wrote:

Hmmmm... so if you define a templated function

template<class T> iseq(T);

and then later add

template<> iseq(SomeType);

then the second is a function overload not a specialization?


this is template function specialisation.
That is
what I am trying to do (I think). Its just that when SomeType is
'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
'template<>' like I have here...


yes, u shud write:

template<> template <typename T1, typename T2> iseq(pair<T1, T2>)


What is the above supposed to be? It isn't legal code, in any case.

Tom
Jul 19 '05 #9
>

template<> template <typename T1, typename T2> iseq(pair<T1, T2>)


What is the above supposed to be? It isn't legal code, in any case.


see the code below and run it, u will understand what i meant by
above.......... .....(use a good compiler ::-))

#include <iostream>
#include <map>

using namespace std;

template<class T> h(T a) { cout << "h::" << a << endl; }

template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout << "pair::"
<< p.first << ":::" << p.second << endl;}

int main()
{
h(20);
pair<int, float> p(20, 30.34);
h(p);
}

Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
7694
by: Agent Mulder | last post by:
Hi group, I have a problem with partial template specialization. In the code below I have a template struct Music with one method, play(), and three kinds of music, Jazz, Funk and Bach. When I specialize Music<Bach>, I expect that the original play() method is available in the specialization, but it is not. How can I fix this? -X
4
1970
by: TT \(Tom Tempelaere\) | last post by:
Comeau compiler complains (too few arguments for class template "B") at line *** #include <memory> template<typename T, size_t n> struct A {}; template<typename T, size_t n> struct B;
1
1745
by: BekTek | last post by:
I'm still confused about the template partial specialization which is used in many libraries.. due to lack of introduction for beginner.. Could you tell me about that in short? Thanks in advance..
5
6596
by: Levent | last post by:
Hi, Why doesn't this work? (tried with gcc 3.3.3 and VC++ 7.1): #include <iostream> template<class T, unsigned N> struct Foo { void func(); }; template<class T, unsigned N>
4
1860
by: Alfonso Morra | last post by:
Does VC 7.1 support template specialization and partial specialization ?
9
2792
by: Marek Vondrak | last post by:
Hello. I have written the following program and am curious why it prints "1" "2". What are the exact effects of explicitly providing function template parameters at the call? Is the second assign() function really a specialization of the first assign() or is it an assign() overload? Thank you. -- Marek
9
3481
by: stephen.diverdi | last post by:
Can anyone lend a hand on getting this particular template specialization working? I've been trying to compile with g++ 4.1 and VS 2005. //------------------------------------------------------------------ // my regular glass class A { }; // my templated class
8
2971
by: flopbucket | last post by:
Hi, I want to provide a specialization of a class for any type T that is a std::map. template<typename T> class Foo { // ... };
1
2232
by: Ioannis Gyftos | last post by:
Hello, First the code :) /////////////////////////////////////////////////////////////////////////////////// // in another header file namespace LJC{
0
9993
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9842
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11265
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10859
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10487
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8036
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5882
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6078
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4708
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.