 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
nick Guest
|
Posted: Tue Jun 14, 2005 9:47 am Post subject: Template deduction |
|
|
Hi All!
I have code:
#include <iostream>
#include <map>
#include <set>
using namespace std;
template < template
C<T> make_cnt(const T& param) {
C<T> r; r.insert(param); return r;
}
template < template
C<K,V> make_cnt(const pair<K,V>& param) {
C<K,V> r; r.insert(param); return r;
}
int main() {
cout << make_cnt
cout << make_cnt
}
Under gcc 3.3.2 compiles and works fine.
Under free MS VC++ toolkit 2003 I get such error:
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp(12) : see declaration of 'make_cnt'
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp( : see declaration of 'make_cnt'
Where is problem?
Thanks.
Dmitriy.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Tue Jun 14, 2005 7:36 pm Post subject: Re: Template deduction |
|
|
nick wrote:
| Quote: | I have code:
#include <iostream
#include
#include
using namespace std;
template < template
C<T> make_cnt(const T& param) {
C<T> r; r.insert(param); return r;
}
template < template
C<K,V> make_cnt(const pair<K,V>& param) {
C<K,V> r; r.insert(param); return r;
}
int main() {
cout << make_cnt
cout << make_cnt
}
Under gcc 3.3.2 compiles and works fine.
Under free MS VC++ toolkit 2003 I get such error:
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp(12) : see declaration of 'make_cnt'
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp( : see declaration of 'make_cnt'
Where is problem?
|
std::set can take more than one template argument. If that's so in your
implementation, then you can't use it where the compiler expects a single
argument template:
template
template<template class BOO {};
template<template class OK {};
BOO<TAB> booboo; // error
OK<TAB> okiedokie;
The template argument 'TT' of template 'BOO' has only one argument, the
template 'TAB' needs two.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
nick Guest
|
Posted: Tue Jun 14, 2005 7:38 pm Post subject: Re: Template deduction |
|
|
Oops, I found typo:
| Quote: | | cout << make_cnt
replace to: |
cout<< make_cnt
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
werasmus Guest
|
Posted: Wed Jun 15, 2005 9:34 am Post subject: Re: Template deduction |
|
|
Hi Dmitriy,
Gcc 3.3.2 probably uses some form of relaxed matching of template
template parameters (basically boils down to ignoring the defaults).
The definition of set (from SGI STL documentation, as well as the MS
VC++ .net 2003 sourcecode) is something like:
set<Key, Compare, Alloc> or...
template<
class _Kty, //Key
class _Pr = less<_Kty>, //Compare, default being less
class _Alloc = allocator<_Kty> > //Allocator
class set...
Clearly, from this it can be seen that set is a class template
requiring 3 template parameters (I think this is std).
Your template function make_cnt...
/////
template < template
C<T> make_cnt(const T& param)
{
C<T> r; r.insert(param); return r;
}
/////
....requires a class template having only one template parameter.
According to "C++ Templates, The Complete Guide" by Josuttis and
Vandevoorde, p111.
"A template template argument must be a class template with parameters
that exactly match the parameters of the template template parameter it
substitutes."
std::set has 3 parameters, make_cnt only specifies one, therefore no
match. Because 2 of std::set params have default values, Gnu seems to
ignore them, whilst the other compiler does not (which is more iaw.
what the std specifies). The fix is to add 2 parameters with defaults
to the template template param, making their defaults the same as that
of set's defaults (this is defined in the std as being std::less and
std::allocator).
Therefore:
template <
template <
class key,
class compare = std::less
class alloc = std::allocator<key> > class contT,
class T >
contT<T> make_cnt(const T& param)
{
contT<T> r; //Uses defaults of contT
r.insert(param);
return r;
}
As they state in "C++ templates", this is not satisfactory, but it
handles the std container types...
Cheers,
Werner
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ismail Pazarbasi Guest
|
Posted: Wed Jun 15, 2005 9:36 am Post subject: Re: Template deduction |
|
|
As far as I can see, yes, there are problems. What about C, K and V?
You have not specified them. There is no specialization either. Also,
set is a template, too. But you have not specified that. Finally, how
do you construct "pair" like that? Something similar to your code could
be:
template<typename T, typename U>
class Dummy
{
};
template<typename T, template
class V>
C<K, V> make_cnt(const pair<K,V>& param)
{
C<K, V> c;
return c;
}
make_cnt<set(pair<int, int>(1, 2));
Ismail
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Wed Jun 15, 2005 10:25 am Post subject: Re: Template deduction |
|
|
In article <1118740519.603029.225240 (AT) f14g2000cwb (DOT) googlegroups.com>,
nick <nick (AT) bel (DOT) ru> wrote:
| Quote: | Hi All!
I have code:
#include <iostream
#include
#include
using namespace std;
template < template
C<T> make_cnt(const T& param) {
C<T> r; r.insert(param); return r;
}
template < template
C<K,V> make_cnt(const pair<K,V>& param) {
C<K,V> r; r.insert(param); return r;
}
int main() {
cout << make_cnt
cout << make_cnt
}
Under gcc 3.3.2 compiles and works fine.
Under free MS VC++ toolkit 2003 I get such error:
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp(12) : see declaration of 'make_cnt'
make_cnt.cpp(17) : error C3208: 'make_cnt' : template parameter list
for class template 'std::set' does not match template parameter list
for template template parameter 'C'
make_cnt.cpp( : see declaration of 'make_cnt'
Where is problem?
Thanks.
Dmitriy.
the standardd says |
template
A=std::allocator<T> >
class set;
not template <class T> class set;
default template parameters are a short hand and not a type changer
set <int> a is the same as set<int,std::less.
similiar problem with map.
A solution:
template <class C>
C make_cont(typename C::const_reference x)
{
C c;
c.insert(x);
return c;
}
will compile with any container with a typedef member const_reference
and insert method(const_reference). This includes all STL containers
and
works with short hand instances like std::set<int> as well. Should
even work in vc 6.x:)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
nick Guest
|
Posted: Wed Jun 15, 2005 10:27 am Post subject: Re: Template deduction |
|
|
But what about this:
class C {};
template<class A, class B = C> class TAB {};
template<template class BOO {};
template<template class OK {};
BOO<TAB> booboo; // no error in g++, but in VC++ error
OK<TAB> okiedokie;
Who is right?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Wed Jun 15, 2005 11:05 pm Post subject: Re: Template deduction |
|
|
nick wrote:
| Quote: | But what about this:
class C {};
template<class A, class B = C> class TAB {};
template<template class BOO {};
template<template class OK {};
BOO<TAB> booboo; // no error in g++, but in VC++ error
OK<TAB> okiedokie;
Who is right?
|
It's been already explained. TAB has 2 arguments. To be used as
a template template argument, the argument needs to be declared to
have 2 arguments (both 'class', BTW). IOW, VC++ is right to flag this
code as ill-formed and g++ probably claims its behaviour as another
"extension".
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|