C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Template deduction

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
nick
Guest





PostPosted: Tue Jun 14, 2005 9:47 am    Post subject: Template deduction Reply with quote



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(Cool : 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





PostPosted: Tue Jun 14, 2005 7:36 pm    Post subject: Re: Template deduction Reply with quote



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(Cool : 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





PostPosted: Tue Jun 14, 2005 7:38 pm    Post subject: Re: Template deduction Reply with quote



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





PostPosted: Wed Jun 15, 2005 9:34 am    Post subject: Re: Template deduction Reply with quote

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





PostPosted: Wed Jun 15, 2005 9:36 am    Post subject: Re: Template deduction Reply with quote

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





PostPosted: Wed Jun 15, 2005 10:25 am    Post subject: Re: Template deduction Reply with quote

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(Cool : 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





PostPosted: Wed Jun 15, 2005 10:27 am    Post subject: Re: Template deduction Reply with 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?


[ 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





PostPosted: Wed Jun 15, 2005 11:05 pm    Post subject: Re: Template deduction Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.