Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How can we point to itself in template parameter

Reply
Thread Tools

How can we point to itself in template parameter

 
 
Grizlyk
Guest
Posts: n/a
 
      01-28-2007
Grizlyk wrote:

I need to point self class in template parameter, for example

template <
class Tptr,
class Tc_iterator
>

class Vcontainer
{
public:
virtual void add_befor(Tc_iterator&, const Tptr);

virtual ~Vcontainer(){}
};

template <
class Tptr,
class Tc_container
>

class Viterator
{
public:
virtual char next(const char is_check_bound=0);

Tc_container *container;

virtual ~Viterator(){}
};

class Tptr;
Viterator< Tptr, Vcontainer<Tptr,"Viterator"> > a;

How can we point to itself here: "Viterator" (after class "Viterator" has
been declared)?

We need only name of class in the case. It can be easy done for non-template
class

class X
{
public:
X* next; //I can do it
};


--
Maksim A Polyanin


 
Reply With Quote
 
 
 
 
terminator
Guest
Posts: n/a
 
      01-28-2007


On Jan 28, 2:52 pm, "Grizlyk" <(E-Mail Removed)> wrote:
> Grizlyk wrote:I need to point self class in template parameter, for example
>
> template <
> class Tptr,
> class Tc_iterator
> >

> class Vcontainer
> {
> public:
> virtual void add_befor(Tc_iterator&, const Tptr);
>
> virtual ~Vcontainer(){}
>
> };template <
> class Tptr,
> class Tc_container
> >

> class Viterator
> {
> public:
> virtual char next(const char is_check_bound=0);
>
> Tc_container *container;
>
> virtual ~Viterator(){}
>
> };class Tptr;
> Viterator< Tptr, Vcontainer<Tptr,"Viterator"> > a;
>
> How can we point to itself here: "Viterator" (after class "Viterator" has
> been declared)?
>
> We need only name of class in the case. It can be easy done for non-template
> class
>
> class X
> {
> public:
> X* next; //I can do it
>
> };--
> Maksim A Polyanin


A template is not a typename unless its arguments are evaluated
first .So you can not recurse when sending parameters to a
template.BUT I just successfully tested the following nestrick
(nesting trick) on VC7.I wanted to pass the "generic" template to
itself as an argument:

template <typename ty>
struct generic{
typedef typename ty::TResult * TPointer;
TPointer ptr;
};

template<typename ty>
struct type{//for every other type
typedef ty TResult;
};

struct generic_self{//for generic itself only
typedef generic<generic_self> TResult;
};

generic< type<int> > Gi; //a generic for int
generic< generic_self > GG; //a generic for generic

 
Reply With Quote
 
 
 
 
terminator
Guest
Posts: n/a
 
      01-28-2007


On Jan 28, 2:52 pm, "Grizlyk" <(E-Mail Removed)> wrote:
> Grizlyk wrote:I need to point self class in template parameter, for example
>
> template <
> class Tptr,
> class Tc_iterator
> >

> class Vcontainer
> {
> public:
> virtual void add_befor(Tc_iterator&, const Tptr);
>
> virtual ~Vcontainer(){}
>
> };template <
> class Tptr,
> class Tc_container
> >

> class Viterator
> {
> public:
> virtual char next(const char is_check_bound=0);
>
> Tc_container *container;
>
> virtual ~Viterator(){}
>
> };class Tptr;
> Viterator< Tptr, Vcontainer<Tptr,"Viterator"> > a;
>
> How can we point to itself here: "Viterator" (after class "Viterator" has
> been declared)?
>
> We need only name of class in the case. It can be easy done for non-template
> class
>
> class X
> {
> public:
> X* next; //I can do it
>
> };--
> Maksim A Polyanin


A template is not a typename unless its arguments are evaluated
first .So you can not recurse when sending parameters to a
template.BUT I just successfully tested the following nestrick
(nesting trick) on VC7.I wanted to pass the "generic" template to
itself as an argument:

template <typename ty>
struct generic{
typedef typename ty::TResult * TPointer;
TPointer ptr;
};

template<typename ty>
struct type{//for every other type
typedef ty TResult;
};

struct generic_self{//for generic itself only
typedef generic<generic_self> TResult;
};

generic< type<int> > Gi; //a generic for int
generic< generic_self > GG; //a generic for generic

 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      01-28-2007


On Jan 28, 3:52 am, "Grizlyk" <(E-Mail Removed)> wrote:
> Grizlyk wrote:I need to point self class in template parameter, for example
> template <
> class Tptr,
> class Tc_container
> >

> class Viterator
> {
> public:
> virtual char next(const char is_check_bound=0);
>
> Tc_container *container;
>
> virtual ~Viterator(){}
>
> };
>
> class Tptr;
> Viterator< Tptr, Vcontainer<Tptr,"Viterator"> > a;
>
> How can we point to itself here: "Viterator" (after class "Viterator" has
> been declared)?


There is no class named Viterator - only a class template named
Viterator. And a class template is not a class - nor even a type.

Now it is possible to create classes from the Viterator class
template. Classes created in this way are named VIterator<Type1,
Type2> where Type1 and Type2 are the names of the parameterized types
used to instantiate the Viterator class template.

> We need only name of class in the case. It can be easy done for non-template
> class
>
> class X
> {
> public:
> X* next; //I can do it
>
> };--


Viterator can do the same:

template <class T1, class T2>
class Viterator
{
public:
Viterator * next;
...
};

But the actual request in this case is entirely different.
Essentially, the aim is to instantiate the class template,
Viterator,with two types: T1 and T2, and have T2 be the type:
Viterator<T1, T2>. In other words T2 in Viterator<T1, T2> is supposed
to be none other than Viterator<T1, T2> itself.

Well, it would be a neat trick if it could be pulled off, but sadly,
it's not possible in C++ to instantiate a class template with the
complete, instantiated type as one of its own type parameters. In
other words, in order to instantaite Viterator in this case, the
program must first instantiate Viterator, but before that can be done,
the program must first instantiate Viterator - and so on and so forth.
So even if this kind of self-referential instantiation were allowed in
C++ - the infinite recursion involved would translate into a long wait
for the program to finish compiling.

Greg

 
Reply With Quote
 
Grizlyk
Guest
Posts: n/a
 
      01-28-2007
Greg wrote:
>
> So even if this kind of self-referential instantiation were allowed in
> C++ - the infinite recursion involved would translate into a long wait
> for the program to finish compiling.



Not of course, no recursion here. In my example class template parameter
refering to self class, so compiler can delay generating concrete class till
all class declaration will be read (to point "};").

C++ must allow to do something like this
typedef Viterator< Tptr, Vcontainer<Tptr,Viterator > > Tc_iterator;

Using a template name without template parameters is allowed in other
places, for example
virtual ~Viterator(){} // not Viterator< T1, T2 >

We can do something like this manualy (it can be compiled)

template <
class Tptr,
class Tc_iterator
>

class Vcontainer
{
public:
virtual void add_befor(Tc_iterator&, const Tptr);

virtual ~Vcontainer(){}
};

template <
class Tptr,
class Tc_container
>

class Viterator
{
public:
virtual char next(const char is_check_bound=0);

Tc_container *container;

virtual ~Viterator(){}
};

class Tptr;

//typedef Viterator< Tptr, Vcontainer<Tptr,Viterator> > Tc_iterator;
class Tc_iterator;

Viterator< Tptr, Vcontainer<Tptr,Tc_iterator> > a;

//at the point inheritance do nothing except introducing new name
class Tc_iterator: public Viterator< Tptr, Vcontainer<Tptr,Tc_iterator> >
{
};

class Tptr{};
typedef Viterator< Tptr, Vcontainer<Tptr,Viterator> > Tc_iterator2;

Vcontainer < Tptr, Tc_iterator2 > b;

void foo()
{
a.container=0;
b.add_befor(a,Tptr());
}

--
Maksim A Polyanin


 
Reply With Quote
 
Grizlyk
Guest
Posts: n/a
 
      01-28-2007
> class Tptr{};
> typedef Viterator< Tptr, Vcontainer<Tptr,Viterator> > Tc_iterator2;
>


No, error
typedef Viterator< Tptr, Vcontainer<Tptr,Tc_iterator> > Tc_iterator2;

> Vcontainer < Tptr, Tc_iterator2 > b;
>
> void foo()
> {
> a.container=0;
> b.add_befor(a,Tptr());
> }
>


--
Maksim A Polyanin


 
Reply With Quote
 
Grizlyk
Guest
Posts: n/a
 
      01-28-2007
Maybe like this:

//make new name with the help of inheritance
template<class Tptr>
class Tc_iterator:
public Viterator<
Tptr,
Vcontainer<Tptr,Tc_iterator<Tptr> >
>

{
};

class Tptr{};
Tc_iterator<Tptr> a;
Vcontainer < Tptr, Tc_iterator<Tptr> > b;

int main()
{
a.container=&b;
b.add_befor(a,Tptr());
}

--
Maksim A Polyanin


 
Reply With Quote
 
terminator
Guest
Posts: n/a
 
      01-28-2007


On Jan 28, 6:52 pm, "Grizlyk" <(E-Mail Removed)> wrote:
> Maybe like this:
>
> //make new name with the help of inheritance
> template<class Tptr>
> class Tc_iterator:
> public Viterator<
> Tptr,
> Vcontainer<Tptr,Tc_iterator<Tptr> >
> >

> {
>
> };class Tptr{};
> Tc_iterator<Tptr> a;
> Vcontainer < Tptr, Tc_iterator<Tptr> > b;
>
> int main()
> {
> a.container=&b;
> b.add_befor(a,Tptr());
>
> }--
> Maksim A Polyanin


You lose a lot in this way the constructors are not usable after
inheritance and actualy you are using a different type which might
cause pointer casting problems later.If you think that you might need
to pass the the type as the argument to itself its better to device
the trick I mentioned in my previous post.Moreover most of the time
such programs behave like worms because of program rational defects ;
this case is different from self pointing classes you pointed in your
previous post.

>We need only name of class in the case. It can be easy done for non-template
>class


>class X
>{
>public:
> X* next; //I can do it
>};



 
Reply With Quote
 
Grizlyk
Guest
Posts: n/a
 
      01-28-2007
terminator wrote:
>
> If you think that you might need
> to pass the the type as the argument to itself its better to device
> the trick I mentioned in my previous post.


Yes.

--
Maksim A Polyanin


 
Reply With Quote
 
terminator
Guest
Posts: n/a
 
      01-29-2007


On Jan 28, 8:26 pm, "Grizlyk" <(E-Mail Removed)> wrote:
> terminator wrote:
>
> > If you think that you might need
> > to pass the the type as the argument to itself its better to device
> > the trick I mentioned in my previous post.

>Yes.
>
> --
> Maksim A Polyanin


check this too:


template <typename traits>
struct generic2 {
typedef typename traits::first first;
typedef typename traits::second second;
first * ptr1;
second * ptr2;
};

template <typename A,typename B>
struct for_2_types{
typedef A first;
typedef B second;
};

template <typename B>
struct generic_self_1{
typedef generic2<generic_self_1> first;
typedef B second;
};

template <typename A>
struct generic_self_2{
typedef A first;
typedef generic2<generic_self_2> second;
};


struct generic_self_both{
typedef generic2<generic_self_both> first,second;
};

// generic2 for int,double
generic2<for_2_types<int,double> > G_id;

// generic2 for generic2,float
generic2<generic_self_1<float> > G_Gf;

// generic2 for char,generic2
generic2<generic_self_2<char> > G_cG;

// generic2 for generic2,generic2
generic2<generic_self_both > G_GG;


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Share-Point-2010 ,Share-Point -2010 Training , Share-point-2010Hyderabad , Share-point-2010 Institute Saraswati lakki ASP .Net 0 01-06-2012 06:39 AM
obtain element name, or attribute and value of the document name itself, and some elemnts and attributes from an ancestor or the node itself using xquery Jeff Kish XML 4 10-30-2008 05:47 PM
Using declaration inside first template parameter as default valuefor second template parameter. Stuart Redmann C++ 5 12-14-2007 08:42 AM
Scenario 5: IS-IS routing on Frame Relay Multi-point and Point-to-Point David Sudjiman Cisco 0 06-08-2006 09:11 AM



Advertisments