From: kvnil on

Hi,

1.

I have a syntax question (I am not trying to write container independent
code). I would like to specify a container and its type, as for example,
"something<int,vector>" where the "int" would be passed to the "vector".
However, I can't get the syntax right, as apparently the default arguments,
i.e., allocator in the code below, is ignored.
It seems that U<T> is wrong, as U has to have two arguments. However, one
of them should be automatically deduced. Nevertheless it doesn't compile.

------------- warning: the code below doesn't compile with VS2005, see comment
---------------
#include <vector>
#include <list>
using namespace std;

template<class T, template<class,class> class U>
class wrapper {
U<T> holder; // doesn't compile!
public:
size_t size() { return holder.size(); }
};

int _tmain(int argc, char* argv[]) {
wrapper<int,vector> x;
wrapper<int,list> y;
printf("%d,%d\n",x.size(),y.size());
}

2.
Or even take this simple example:

How can one avoid specifying arguments in declaration of variable v_ ?

template<typename T1 = float, typename T2 = int> class X1 { };

template<template<typename,typename> class U = X1> class X2 { };
int main(int, char**)
{
X2 v_; // doesn't compile
}




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Barry on
On 4月4日, 下午9时33分, kvnil <kv...(a)mail.ru> wrote:
> Hi,
>
> 1.
>
> I have a syntax question (I am not trying to write container independent
> code). I would like to specify a container and its type, as for example,
> "something<int,vector>" where the "int" would be passed to the "vector".
> However, I can't get the syntax right, as apparently the default arguments,
> i.e., allocator in the code below, is ignored.
> It seems that U<T> is wrong, as U has to have two arguments. However, one
> of them should be automatically deduced. Nevertheless it doesn't compile.
>
> ------------- warning: the code below doesn't compile with VS2005, see comment
> ---------------
> #include <vector>
> #include <list>
> using namespace std;
>
> template<class T, template<class,class> class U>
> class wrapper {
> U<T> holder; // doesn't compile!
> public:
> size_t size() { return holder.size(); }
>
> };
>
> int _tmain(int argc, char* argv[]) {
> wrapper<int,vector> x;
> wrapper<int,list> y;
> printf("%d,%d\n",x.size(),y.size());
>
> }

by removing the declaration of "x" and "y", we still get the error,
which means that your definition of template class "wrapper" was
wrong,
so the using of "vector"/"list" has nothing to do with the error, the
compiler
does not foresee that you're using a template with default argument.
when you
declared "U<T> holder", the compiler notify that the number of
template parameter
does not match the number of template argument.

solution:

template<class T, template<class Ty, class = std::allocator<Ty> >
class U>
class wrapper {
....
};

>
> 2.
> Or even take this simple example:
>
> How can one avoid specifying arguments in declaration of variable v_ ?
>
> template<typename T1 = float, typename T2 = int> class X1 { };
>
> template<template<typename,typename> class U = X1> class X2 { };
> int main(int, char**)
> {
> X2 v_; // doesn't compile

X2<> v_; // you can't even ignore <>, which indicate X2 is a
template.

>
> }
>

HTH

--
Best Regards
Barry


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Baheti, Sarang on
{ Edits: "Subject" header corrected, was "subject", and banner area contents
corrected. Please note that articles with malformed headers cause problems and
will not necessarily be propagated by Usenet servers. Using a different Usenet
client, or simply using a Usenet client, might cure the problem. -mod }

Hi,

1.

I have a syntax question (I am not trying to write container independent
code). I would like to specify a container and its type, as for
example,
"something<int,vector>" where the "int" would be passed to the "vector".
However, I can't get the syntax right, as apparently the default
arguments,
i.e., allocator in the code below, is ignored.
It seems that U<T> is wrong, as U has to have two arguments. However,
one
of them should be automatically deduced. Nevertheless it doesn't
compile.

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

#include <vector>
#include <list>


template<class T, template<class T1 = T,class Alloc = std::allocator<T1>
> class U>
class wrapper
{
U<T> holder; // doesn't compile!
public:
size_t size() { return holder.size(); }
};


int main()
{
wrapper<int, std::vector> intVec;
intVec.size();

wrapper<int, std::list> intlist;
intVec.size();

return 0;
}
------------------------------------------------------------------------
-
2.
Or even take this simple example:

How can one avoid specifying arguments in declaration of variable v_ ?

template<typename T1 = float, typename T2 = int> class X1 { };

template<template<typename,typename> class U = X1> class X2 { };
int main(int, char**)
{
X2<> v_; // use default parameters
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alberto Ganesh Barbati on
kvnil ha scritto:
> ------------- warning: the code below doesn't compile with VS2005, see
> comment
> ---------------
> #include <vector>
> #include <list>
> using namespace std;
>
> template<class T, template<class,class> class U>
> class wrapper {
> U<T> holder; // doesn't compile!

U is declared to be a template expecting two arguments and you are
providing only one of them. You must provide both. Please notice that in
this context you can't access any default argument that actual argument
replacing U might have in the instantiation context.

> public:
> size_t size() { return holder.size(); }
> };
>
> int _tmain(int argc, char* argv[]) {
> wrapper<int,vector> x;
> wrapper<int,list> y;
> printf("%d,%d\n",x.size(),y.size());
> }
>
> 2.
> Or even take this simple example:
>
> How can one avoid specifying arguments in declaration of variable v_ ?
>
> template<typename T1 = float, typename T2 = int> class X1 { };
>
> template<template<typename,typename> class U = X1> class X2 { };
> int main(int, char**)
> {
> X2 v_; // doesn't compile
> }
>

The problem is the same as above, let me explain it with different
words: in the context of function main X1<> has two default parameters,
but in the context of the template wrapper, U<> still has no default
parameters. When instantiating the template, it's just the name X1 that
replaces U, U doesn't get the default parameters that X1 has. In fact
you could even provide U with default parameters which would be valid in
the context of wrapper:

template<class T, template<class I,class = std::allocator<I> > class U>
class wrapper {
...
};

However, please notice that standard container have *at least* two
parameters, but they may have more, so using template template
parameters is not going to be portable, as you must specify the exact
number of parameters. The morale is that template template parameters
are less useful than one may think.

HTH,

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]