473,238 Members | 1,747 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,238 software developers and data experts.

Class template specialization with template parameter

Hi,

I want to provide a specialization of a class for any type T that is a
std::map.

template<typename T>
class Foo
{
// ...
};

template<typename K, typename V>
class Foo<std::map<K, V
{
// ...
};

It seems to work - is this the correct way to do this?

Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?

Thanks

Jun 27 '08 #1
8 2910
flopbucket wrote:
Hi,

I want to provide a specialization of a class for any type T that is a
std::map.

template<typename T>
class Foo
{
// ...
};

template<typename K, typename V>
class Foo<std::map<K, V
{
// ...
};

It seems to work - is this the correct way to do this?
Correct for what? If it works for you, it must be "correct".
Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?
Not sure what you're asking here.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #2
Hi,

First, thanks for the reply.

Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?

Not sure what you're asking here.
What I was trying to say was that if I declare:

Foo<intmyFoo();

The instantiation will be for the normal/not-specialized template.

But if I declare:

Foo<std::map<int, std::string myFoo2();

it will use the specialization... and that regardless of the types
used for std::map (in this case, int and std::string), any
"Foo<std::map<typeA, typeB myFooExample()" will always
instantiate the specialization.

Thanks
Jun 27 '08 #3
flopbucket wrote:
Hi,

First, thanks for the reply.

>>Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?
Not sure what you're asking here.

What I was trying to say was that if I declare:

Foo<intmyFoo();

The instantiation will be for the normal/not-specialized template.
Yes. Of course, 'myFoo' in that case is a function, but the template
is still instantiated, I believe.
>
But if I declare:

Foo<std::map<int, std::string myFoo2();
Same thing. It's a function. But the 'std::map'-based specialisation
should be used, of course.
it will use the specialization... and that regardless of the types
used for std::map (in this case, int and std::string), any
"Foo<std::map<typeA, typeB myFooExample()" will always
instantiate the specialization.
Yes. Or do you still have a doubt about that?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #4
On May 14, 12:51*pm, flopbucket <flopbuc...@hotmail.comwrote:
Hi,

First, thanks for the reply.
Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?
Not sure what you're asking here.

What I was trying to say was that if I declare:

Foo<intmyFoo();
I believe that you mean to declare an object (and not a function):

Foo<intmyFoo;
The instantiation will be for the normal/not-specialized template.
Yes.
But if I declare:

Foo<std::map<int, std::string myFoo2();
Again, I believe that you want:

Foo<std::map<int, std::string myFoo2;
it will use the specialization... and that regardless of the types
used for std::map (in this case, int and std::string), any
"Foo<std::map<typeA, typeB *myFooExample()" *will always
instantiate the specialization.
The answer depends on how many template parameters "std::map"
requires. The usual number is two - the two specified by the C++
Standard. An implementation however is allowed to require additional
temmplate type parameters for a std::map. So, assuming that std::map
requires only two type parameters, then the answer is "yes".

Greg

Jun 27 '08 #5
>
Yes. Of course, 'myFoo' in that case is a function, but the template
is still instantiated, I believe.
Right, my mistake. Should bee 'Foo<intmyFoo;'
>
Yes. Or do you still have a doubt about that?
No, thanks, just wanted to run it by some experts - I've done
specializations before but this one was a bit more "advanced" then
normal basic types, since std::map<itself is a template. I just
wasn't sure of myself.

Thanks for the clarifications.
Jun 27 '08 #6
Greg Herlihy wrote:
On May 14, 12:51 pm, flopbucket <flopbuc...@hotmail.comwrote:
>Hi,

First, thanks for the reply.
>>>Foo<intuses the normal template, but Foo<std::map<T1, T2 for any
types of T1 and T2 uses the specifalization?
Not sure what you're asking here.
What I was trying to say was that if I declare:

Foo<intmyFoo();

I believe that you mean to declare an object (and not a function):

Foo<intmyFoo;
>The instantiation will be for the normal/not-specialized template.

Yes.
>But if I declare:

Foo<std::map<int, std::string myFoo2();

Again, I believe that you want:

Foo<std::map<int, std::string myFoo2;
>it will use the specialization... and that regardless of the types
used for std::map (in this case, int and std::string), any
"Foo<std::map<typeA, typeB myFooExample()" will always
instantiate the specialization.

The answer depends on how many template parameters "std::map"
requires. The usual number is two - the two specified by the C++
Standard. An implementation however is allowed to require additional
temmplate type parameters for a std::map. So, assuming that std::map
requires only two type parameters, then the answer is "yes".
I don't think it has anything to do with the number of arguments the
template takes/has. The specialisation is not a template with a
template template argument (I believe that's what you're thinking of...)

For instance,

template<class T, class U = intclass TwoArgs {};
template<class Tstruct Foo { enum {a=0}; };
template<class Tstruct Foo<TwoArgs<T { enum {a=1}; };

int main() {
char should_complain[Foo<char>::a];
char dont_know[Foo<TwoArgs<int,char::a];
char should_be_OK[Foo<TwoArgs<double::a];
}

The declaration of 'should_complain' instantiates the regular 'Foo'
because it's not the specialisation on 'TwoArgs'. The declaration of
'should_be_OK' is the specialisation which has 'a == 1'. Now, since
'dont_know' uses the 'Foo' instantiated for 'TwoArgs', yet the second
argument of 'TwoArgs' is not the default (int), I am not sure. The
Comeau online test drive does not like 'dont_know', most likely because
it uses the 'TwoArgs' in a way different from the specialisation's, and
as the result 'a' is 0. Tricky...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #7
On May 14, 10:20 pm, Greg Herlihy <gre...@mac.comwrote:
On May 14, 12:51 pm, flopbucket <flopbuc...@hotmail.comwrote:
Foo<intuses the normal template, but Foo<std::map<T1,
T2 for any types of T1 and T2 uses the
specifalization?
Not sure what you're asking here.
What I was trying to say was that if I declare:
Foo<intmyFoo();
I believe that you mean to declare an object (and not a function):
Foo<intmyFoo;
The instantiation will be for the normal/not-specialized template.
Yes.
But if I declare:
Foo<std::map<int, std::string myFoo2();
Again, I believe that you want:
Foo<std::map<int, std::string myFoo2;
it will use the specialization... and that regardless of the types
used for std::map (in this case, int and std::string), any
"Foo<std::map<typeA, typeB myFooExample()" will always
instantiate the specialization.
The answer depends on how many template parameters "std::map"
requires. The usual number is two - the two specified by the
C++ Standard.
The usual number is four, since that's what the C++ standard
requires. He has defined a partial specialization for Foo<
std::map< T, U, std::less<T>, std::allocator< std::pair< T
const, U . If he instantiates Foo with a type which
corresponds to this, the partial specialization will be used.
Otherwise, the non-specialized version will be used. Thus, with
std::map< int, std::string (or std::map< int, std::string,
std::less< int ), he'll get the partial specialization, but
with std::map< std::string, int, CaseInsensitiveCompare >, he'll
get the non-specialized version.
An implementation however is allowed to require additional
temmplate type parameters for a std::map.
But only if they follow the required four, and have default
values. So as long as you don't use them, his code should work.
So, assuming that std::map requires only two type parameters,
then the answer is "yes".
Assuming that the implementation of std::map is conform, his
partial specialization will be used for all std::map
instantiations which use std::less<Keyas the comparator, and
std::allocator< std::pair< Key const, T as the allocator.
(Using something other than the default allocator is fairly
rare, but it's quite frequent to find map's with other than the
default comparison function. In his case, I would definitly add
that to the arguments of the partial specialization. And it's
not that difficult to add the allocator either:

template< typename Key, typename Value,
typename Cmp, typename Alloc >
class Foo< std::map< Key, Value, Cmp, Alloc
{
// ...
} ;

This should work for all instanciations of std::map.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #8
On May 14, 3:28*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Greg Herlihy wrote:
The answer depends on how many template parameters "std::map"
requires. The usual number is two - the two specified by the C++
Standard. An implementation however is allowed to require additional
temmplate type parameters for a std::map. So, assuming that std::map
requires only two type parameters, then the answer is "yes".

I don't think it has anything to do with the number of arguments the
template takes/has. *The specialisation is not a template with a
template template argument (I believe that's what you're thinking of...)

For instance,

* * *template<class T, class U = intclass TwoArgs {};
* * *template<class Tstruct Foo { enum {a=0}; };
* * *template<class Tstruct Foo<TwoArgs<T { enum {a=1}; };

* * *int main() {
* * * * *char should_complain[Foo<char>::a];
* * * * *char dont_know[Foo<TwoArgs<int,char::a];
* * * * *char should_be_OK[Foo<TwoArgs<double::a];
* * *}

The declaration of 'should_complain' instantiates the regular 'Foo'
because it's not the specialisation on 'TwoArgs'. *The declaration of
'should_be_OK' is the specialisation which has 'a == 1'. *Now, since
'dont_know' uses the 'Foo' instantiated for 'TwoArgs', yet the second
argument of 'TwoArgs' is not the default (int), I am not sure. *The
Comeau online test drive does not like 'dont_know', most likely because
it uses the 'TwoArgs' in a way different from the specialisation's, and
as the result 'a' is 0. *Tricky...
I agree with Comeau compiler that TwoArgs<int,charwill not match the
provided "TwoArgs" specialization, since "char" is not default
argument type for TwoArg<>'s second type parameter.

Anyway, as James points out a std::map actually accepts (at least)
four template type parameters. Now, since the original program
specified only two of those four type parameters, the two unspecified
type parameters assume their default type arguments.

So, if the program instantiates the Foo template with a std::map class
that was in turn instantiated with a non-default Allocator class -
then the std::map specialization will not be selected. Therefore, to
ensure that any and all std::map classes (no matter their template
type arguments) always use Foo<>'s std::map specialization, the
declaration of the Foo template must provide as many type arguments
for the std::map specialization as a std::map accepts. For example,
assuming the required four arguments, the declaration of Foo<should
look more like this:

template<class T1, class T2, class T3, class T4>
class Foo<std::map<T1, T2, T3, T4
{
// ...
};

In that way, std::map's instantiated with non-default template type
arguments - will still select Foo's partial specialization for
std::maps.

Greg

Jun 27 '08 #9

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

Similar topics

2
by: Jeff | last post by:
/* -------------------------------------------------------------------------- Hello, I was experimenting with class templates and specializing member functions and came across a simple problem...
13
by: Walt Karas | last post by:
The following gives an error in the declaration of the member function x() of the class template Tpl, compiliing with a recent version of GCC under Solaris: class A { }; class B { }; ...
2
by: Bjoern Knafla | last post by:
Hi! I am trying to specialize a member function of a template class (see code below). The moment the header with the "template class definition" and "template class member function...
3
by: danilo.horta | last post by:
Hi guys I'm trying to accomplish a slightly difficult task. I think it's more easy to explain trought an unworking code: template<class T, size_t numDim> VecBasis {/*...*/}; typedef...
4
by: Joseph Turian | last post by:
Hi, What is the correct syntax to get the bar<T>::f<int, unsigned>() function to compile in the following fragment? Thanks, Joseph class foo {
9
by: Adam Badura | last post by:
I have code like this template<int size> big_int { /* ... */ template<int size2> friend class big_int<size2>; }; What I wanted to achive is to be able to easly convert different sized...
17
by: Jef Driesen | last post by:
Suppose I have a datastructure (actually it's a graph) with one template parameter (the property P for each edge and vertex): struct graph<P>; struct vertex<P>; struct edge<P>; I also have...
2
by: Barry | last post by:
The following code compiles with VC8 but fails to compiles with Comeau online, I locate the standard here: An explicit specialization of any of the following:
1
by: ctoo | last post by:
The following compiles and works with g++ 3.4.4 and Borland C++ Builder 6 update#4: #include <iostream> #include <vector> #include <utility> // declaration and definition for primary class...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

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.