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 

Identifiers as template parameters?

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





PostPosted: Mon Mar 14, 2005 11:59 pm    Post subject: Identifiers as template parameters? Reply with quote



Given SomeClass:

class SomeClass {
struct Node {
SomeClass* prev;
SomeClass* next;
};

Node node1;
Node node2;
};

Is there any way to create a templated class like the following, where
the '?' in the template specification is some term that can determine
that 'name' is an identifier.

template<typename T, '?' name>
class SomeList {
public:
/* ... */
void append( T* elem ) {
elem->name.prev = mEnd;
elem->name.next = 0;
mEnd->next = elem;
elem = mEnd;
}
/* ... */
private:
T* begin;
T* end;
};

typedef SomeList<SomeClass,node1> Node1List;
typedef SomeList<SomeClass,node2> Node2List;

I'm guessing the answer is "no", but perhaps there's some clever
work-around to get the functionality I want. Otherwise, I'll have to
continue using an ugly macro work-around (which works perfectly, but
its still a macro). But man, it'd be nice to have something like this
in standard C++ (any drawbacks to such an addition?).


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

Back to top
johnchx2@yahoo.com
Guest





PostPosted: Tue Mar 15, 2005 3:50 pm    Post subject: Re: Identifiers as template parameters? Reply with quote



[email]lindahlb (AT) hotmail (DOT) com[/email] wrote:

Quote:
Is there any way to create a templated class like the following,
where the '?' in the template specification is some term that
can determine that 'name' is an identifier.

Not an identifier as such, but you can accomplish what you want by
templating SomeList on a pointer-to-member. Here's a sketch:

struct SomeClass {
struct Node {
SomeClass* prev;
SomeClass* next;
};

Node node1;
Node node2;
};

template <class T, class M, M T::*MP>
struct SomeList {
void Append(T* elem)
{
M& node = elem->*MP;
node.next = 0;
// do other stuff
}
};

typedef SomeList<SomeClass, SomeClass::Node, &SomeClass::node1>
Node1List;
typedef SomeList<SomeClass, SomeClass::Node, &SomeClass::node2>
Node2List;

int main()
{
Node1List n1;
n1.Append(0);
Node2List n2;
n2.Append(0);
}


[ 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 Mar 15, 2005 3:52 pm    Post subject: Re: Identifiers as template parameters? Reply with quote



<lindahlb (AT) hotmail (DOT) com> wrote...
Quote:
Given SomeClass:

class SomeClass {
struct Node {
SomeClass* prev;
SomeClass* next;
};

Node node1;
Node node2;
};

Is there any way to create a templated class like the following, where
the '?' in the template specification is some term that can determine
that 'name' is an identifier.

template<typename T, '?' name

It's called "a pointer to member" and the syntax is

template
Quote:
class SomeList {
public:
/* ... */
void append( T* elem ) {
elem->name.prev = mEnd;

The syntax here is a bit more complicated:

(elem->*name).prev = mEnd;

Quote:
elem->name.next = 0;

Here too:

(elem->*name).next = 0;

Quote:
mEnd->next = elem;
elem = mEnd;
}
/* ... */
private:
T* begin;
T* end;
};

typedef SomeList<SomeClass,node1> Node1List;
typedef SomeList<SomeClass,node2> Node2List;

The syntax here is similar:

typedef SomeList< SomeClass, &SomeClass::node1 > Node1List;
typedef SomeList< SomeClass, &SomeClass::node2 > Node2List;

(spaces are added for readability)

I may have made a mistake somewhere, but this is your general direction.

Quote:

I'm guessing the answer is "no", but perhaps there's some clever
work-around to get the functionality I want. Otherwise, I'll have to
continue using an ugly macro work-around (which works perfectly, but
its still a macro). But man, it'd be nice to have something like this
in standard C++ (any drawbacks to such an addition?).

V



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

Back to top
Maxim Yegorushkin
Guest





PostPosted: Tue Mar 15, 2005 3:58 pm    Post subject: Re: Identifiers as template parameters? Reply with quote

<lindahlb (AT) hotmail (DOT) com> wrote:

Quote:
Given SomeClass:

class SomeClass {
struct Node {
SomeClass* prev;
SomeClass* next;
};

Node node1;
Node node2;
};

Is there any way to create a templated class like the following, where
the '?' in the template specification is some term that can determine
that 'name' is an identifier.

template<typename T, '?' name
class SomeList {
public:
/* ... */
void append( T* elem ) {
elem->name.prev = mEnd;
elem->name.next = 0;
mEnd->next = elem;
elem = mEnd;
}
/* ... */
private:
T* begin;
T* end;
};

typedef SomeList<SomeClass,node1> Node1List;
typedef SomeList<SomeClass,node2> Node2List;

I'm guessing the answer is "no", but perhaps there's some clever
work-around to get the functionality I want. Otherwise, I'll have to
continue using an ugly macro work-around (which works perfectly, but
its still a macro). But man, it'd be nice to have something like this
in standard C++ (any drawbacks to such an addition?).

The most straightforward way to do this is to use member pointers as
template parameters:

template<typename T, typename T::Node T::*node>
struct SomeList {

void append( T* elem ) {
(elem->*node).prev = end;
(elem->*node).next = 0;
end->next = elem;
end = elem;
}

T* begin;
T* end;
};

typedef SomeList<SomeClass, &SomeClass::node1> Node1List;
typedef SomeList<SomeClass, &SomeClass::node2> Node2List;

At times one may want to avoid hardcoding the member (pointer) type at
all. The solution to this is to define names for the data members as types
and then access the members using these types. This way member's type do
not need to be hardcoded:

struct SomeClass {
struct Node {
SomeClass* prev;
SomeClass* next;
};

Node node1;
Node node2;

struct node1_tag {};
struct node2_tag {};

friend Node& get(SomeClass& t, node1_tag) { return t.node1; }
friend Node& get(SomeClass& t, node2_tag) { return t.node2; }
};

template<typename T, typename tag>
struct SomeList {

void append( T* elem ) {
get(*elem, tag()).prev = end;
get(*elem, tag()).next = 0;
end->next = elem;
end = elem;
}

T* begin;
T* end;
};

typedef SomeList<SomeClass, SomeClass::node1_tag> Node1List;
typedef SomeList<SomeClass, SomeClass::node2_tag> Node2List;


--
Maxim Yegorushkin

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


Back to top
gleb.alexeev@gmail.com
Guest





PostPosted: Tue Mar 15, 2005 4:02 pm    Post subject: Re: Identifiers as template parameters? Reply with quote

The example you posted doesn't explain your need for the feature like
this. In most cases for things like list it's better to use standard
library. However if this is just what you need, you can use something
like policies:

template<typename T, class NodeGetter>
class SomeList {
public:
/* ... */
void append( T* elem ) {
SomeClass::Node& node = NodeGetter::get(elem);
node.prev = mEnd;
node.next = 0;
mEnd->next = elem;
elem = mEnd;
}
};

struct Node1Getter {
static SomeClass::Node& get(SomeClass* elem) {
return elem->node1;
}
};
struct Node2Getter {
static SomeClass::Node& get(SomeClass* elem) {
return elem->node2;
}
};

typedef SomeList<SomeClass,Node1Getter> Node1List;
typedef SomeList<SomeClass,Node2Getter> Node2List;


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

Back to top
Robert
Guest





PostPosted: Tue Mar 15, 2005 8:27 pm    Post subject: Re: Identifiers as template parameters? Reply with quote

I believe a pointer-to-member would do the trick here.

template <typename T, T::Node T::*>
class SomeList {
....
}

typedef SomeList<SomeClass, &SomeClass::node1> Node1List;
....

I haven't tried this. Take it for what it is worth.

Robert


[ 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.