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 

Creating a template class based on Barton-Nackman trick

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





PostPosted: Wed Aug 27, 2003 9:46 am    Post subject: Creating a template class based on Barton-Nackman trick Reply with quote



Hi,

I am learning my ways around using templates in c++. I came across a
piece of code below that shows how the Barton Nackman trick worked.
Then I tried to make a tempalte class out of it. And gcc (version
3.2.2) is not happy about it. I wonder if someone can help me out.

-------------------------------------------------------------------------
#include <vector>

template <class Node_Type>
class Basic_Tree_Node
{
private:
unsigned int name;
Node_Type *ptr2parent;
std::vector<Node_Type*> children;

public:
Basic_Tree_Node(unsigned int node_name,
Node_Type *parent)
:name(node_name), ptr2parent(parent) {}

void add_child(unsigned int name)
{
Node_Type *new_node = new Node_Type(name,
static_cast<Node_Type*>(this));
children.push_back(new_node);
}

};

template <int size>
class Special_Tree_Node1 : public Basic_Tree_Node<Special_Tree_Node1>
{
public:
Special_Tree_Node1(unsigned int name,
Special_Tree_Node1 *ptr2parent)
: Basic_Tree_Node<Special_Tree_Node1>(name, ptr2parent) {}

private:
int sz;
};

int main()
{
Special_Tree_Node1<16> stn1(1, 0);
stn1.add_child(2);

return 0;
}

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

The error messages are:

treenode.cpp:26: type/value mismatch at argument 1 in template
parameter list
for `template<class Node_Type> class Basic_Tree_Node'
treenode.cpp:26: expected a type, got `Special_Tree_Node1'
treenode.cpp: In function `int main()':
treenode.cpp:39: no matching function for call to
`Special_Tree_Node1<16>::
add_child(int)'
treenode.cpp: In constructor
`Special_Tree_Node1<size>::Special_Tree_Node1(unsigned int,
Special_Tree_Node1<size>*) [with int size = 16]':
treenode.cpp:38: instantiated from here
treenode.cpp:30: type `class Basic_Tree_Node<Special_Tree_Node1<16> >'
is not a
direct base of `Special_Tree_Node1<16>'

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

The same code compiled fine on MSVC 6.0. Appreciate any comments.

Frank

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





PostPosted: Wed Aug 27, 2003 9:11 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote



Frank wrote:
[SNIP]
Quote:
template <int size
class Special_Tree_Node1 : public Basic_Tree_Node [SNIP]
treenode.cpp:26: expected a type, got `Special_Tree_Node1'
[SNIP]


I might be completely wrong, but as I see it Special_Tree_Node1 is a class
template. A class template is not a type, it will only be a type if
specialized. So as far as I see you will need to write there something
like:

class Special_Tree_Node1 :
public Basic_Tree_Node

But I am not that polished in templates so I might be wrong.

--
Attila aka WW



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

Back to top
Ben Hutchings
Guest





PostPosted: Thu Aug 28, 2003 10:32 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote



In article <f0648a6e.0308261505.47f65990 (AT) posting (DOT) google.com>, Frank wrote:
Quote:
Hi,

I am learning my ways around using templates in c++. I came across a
piece of code below that shows how the Barton Nackman trick worked.
Then I tried to make a tempalte class out of it. And gcc (version
3.2.2) is not happy about it. I wonder if someone can help me out.
snip
template <int size
class Special_Tree_Node1 : public Basic_Tree_Node snip
The error messages are:

treenode.cpp:26: type/value mismatch at argument 1 in template
parameter list
for `template treenode.cpp:26: expected a type, got `Special_Tree_Node1'
snip


The message is fairly clear! Special_Tree_Node1 is not a type; it's
a template. You need to write Special_Tree_Node1<size> instead.

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

Back to top
johnchx
Guest





PostPosted: Thu Aug 28, 2003 10:42 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

[email]an_liqun (AT) yahoo (DOT) com[/email] (Frank) wrote

Quote:
template <int size
class Special_Tree_Node1 : public Basic_Tree_Node

The problem is that Special_Tree_Node1 is the name of a template, not
a type. Try the following:

template class Special_Tree_Node1:
public Base_Tree_Node< Special_Tree_Node1 {
// ...
};

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

Back to top
Ron
Guest





PostPosted: Thu Aug 28, 2003 10:44 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

Quote:
#include <vector

template class Basic_Tree_Node
{
private:
unsigned int name;
Node_Type *ptr2parent;
std::vector
public:
Basic_Tree_Node(unsigned int node_name,
Node_Type *parent)
:name(node_name), ptr2parent(parent) {}

void add_child(unsigned int name)
{
Node_Type *new_node = new Node_Type(name,
static_cast<Node_Type*>(this));
children.push_back(new_node);
}

};

template class Special_Tree_Node1 : public Basic_Tree_Node

Error xyzzy: Template 'Special_Tree_Node1' requires an argument ^

-- Ron

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

Back to top
Rob Williscroft
Guest





PostPosted: Thu Aug 28, 2003 10:57 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

Frank wrote in news:f0648a6e.0308261505.47f65990 (AT) posting (DOT) google.com:

[snip]

Quote:
template <int size
class Special_Tree_Node1 : public Basic_Tree_Node

class Special_Tree_Node1 :
public Basic_Tree_Node< Special_Tree_Node1< size > >


Quote:
{
public:
Special_Tree_Node1(unsigned int name,
Special_Tree_Node1 *ptr2parent)
: Basic_Tree_Node<Special_Tree_Node1>(name, ptr2parent) {}

private:
int sz;
};

int main()
{
Special_Tree_Node1<16> stn1(1, 0);
stn1.add_child(2);

return 0;
}

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

The error messages are:

treenode.cpp:26: type/value mismatch at argument 1 in template
parameter list
for `template<class Node_Type> class Basic_Tree_Node'
treenode.cpp:26: expected a type, got `Special_Tree_Node1'

Reading template errors can be a bit of an art form, but it
is telling you what you need to know.

Special_Tree_Node1 isn't a type its a class-template, only
when you associate it sutible template paramiters does the name
refer to a type, i.e. Special_Tree_Node1< 16 > is a type.

[snip]

Quote:

The same code compiled fine on MSVC 6.0. Appreciate any comments.


Upgrade your version of msvc - if you can't give up on the idea
of using any form of 'advanced' template techniques.


Rob.
--
http://www.victim-prime.dsl.pipex.com/

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

Back to top
Dag Henriksson
Guest





PostPosted: Thu Aug 28, 2003 8:38 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

"Frank" <an_liqun (AT) yahoo (DOT) com> skrev i meddelandet
news:f0648a6e.0308261505.47f65990 (AT) posting (DOT) google.com...
Quote:
Hi,

I am learning my ways around using templates in c++. I came across a
piece of code below that shows how the Barton Nackman trick worked.

Isn't your code an example of the Curiously Recurring Template Pattern, by
Coplien, and not the Barton-Nackman trick? I thought Barton-Nackman trick
was a technique to inject non-template names into the global scope, by using
a friend function. Once upon a time, when templates could not be overloaded,
this was useful.

--
Dag Henriksson




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

Back to top
Richard Smith
Guest





PostPosted: Fri Aug 29, 2003 8:42 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

Frank wrote:

[heavily truncated]

Quote:
template <class Node_Type
class Basic_Tree_Node {};

template class Special_Tree_Node1
: public Basic_Tree_Node {};

As lots of other people have already pointed out, you need
to add template arguments to Special_Tree_Node1. This can
seem quite counter-intuitive given that

template class Special_Tree_Node1 {
Basic_Tree_Node<Special_Tree_Node1> member;
};

compiles just fine. Similarly, when initialising the base
class, it's perfectly legal to omit the template arguments:

Special_Tree_Node1()
: Basic_Tree_Node<Special_Tree_Node1>()
{}

This has always struck me as somewhat inconsistent, and I've
never really understood why it should be like this.

--
Richard Smith

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

Back to top
Daveed Vandevoorde
Guest





PostPosted: Sat Aug 30, 2003 1:50 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

Richard Smith <richard (AT) ex-parrot (DOT) com> wrote:
Quote:
Frank wrote:

[heavily truncated]

template <class Node_Type
class Basic_Tree_Node {};

template class Special_Tree_Node1
: public Basic_Tree_Node {};

As lots of other people have already pointed out, you need
to add template arguments to Special_Tree_Node1. This can
seem quite counter-intuitive given that

template class Special_Tree_Node1 {
Basic_Tree_Node };

compiles just fine. Similarly, when initialising the base
class, it's perfectly legal to omit the template arguments:

Special_Tree_Node1()
: Basic_Tree_Node<Special_Tree_Node1>()
{}

This has always struck me as somewhat inconsistent, and I've
never really understood why it should be like this.

Your comments (with which I might agree) prompted me to
investigate this and it is not all that clear to me that the
standard (TC1) makes the original example invalid.

I base this one three references:

14.6.1/1: The injected class name can be used without a
template argument list (the arguments are then implied).

9/2: The injected class name is injected in the class scope.

3.3.6/1: The class scope includes the declarative region
starting after the declaration of the name.

That last part is not entirely clear: I think the text was written
without consideration for implicit declarations. I'll ask for a
Core WG clarification.

Daveed

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

Back to top
Frank
Guest





PostPosted: Sat Aug 30, 2003 7:59 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

[email]an_liqun (AT) yahoo (DOT) com[/email] (Frank) wrote in message news:<f0648a6e.0308261505.47f65990 (AT) posting (DOT) google.com>...

Thanks for all your responses. All you said are correct. But for some
reason, gcc simply won't compile when I have it like this.

template <int size>
class Special_Tree_Node1 : public
Basic_Tree_Node<Special_Tree_Node1

With a lucky stroke, a space was inserted after <size>, and all of a
sudden, it compiles.

template <int size>
class Special_Tree_Node1 : public
Basic_Tree_Node<Special_Tree_Node1

Is there some rule about the space in defining template parameters?
This is totally nuts.

Frank

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





PostPosted: Sun Aug 31, 2003 5:19 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

Richard Smith <richard (AT) ex-parrot (DOT) com> wrote

Quote:
As lots of other people have already pointed out, you need
to add template arguments to Special_Tree_Node1. This can
seem quite counter-intuitive given that

template <int size
class Special_Tree_Node1 {
Basic_Tree_Node };

compiles just fine. Similarly, when initialising the base
class, it's perfectly legal to omit the template arguments:

Special_Tree_Node1()
: Basic_Tree_Node<Special_Tree_Node1>()
{}

This has always struck me as somewhat inconsistent, and I've
never really understood why it should be like this.

It's a scope thing. ;-)

14.6.1/1 says
Within the scope of a class template, when the name of
the template is neither qualified nor followed by <,
it is equivalent to the name of the template followed
by the template-parameters enclosed in <>.

The base-clause isn't inside the scope of the class, so this rule
doesn't apply there.

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

Back to top
johnchx
Guest





PostPosted: Mon Sep 01, 2003 11:12 am    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

[email]google (AT) vandevoorde (DOT) com[/email] (Daveed Vandevoorde) wrote

Quote:

3.3.6/1: The class scope includes the declarative region
starting after the declaration of the name.

That last part is not entirely clear: I think the text was written
without consideration for implicit declarations. I'll ask for a
Core WG clarification.

3.3.6/1 (1) says:
The potential scope of a name declared in a class consists not only
of the declarative region following the name's declarator....

I don't believe that this can apply to the class name itself because
it has no declarator (thus there is no declarative region following
the name's declarator). The class name appears in the class-head
portion of the class-specifier, which (according to the grammer, A6)
is a type-specifier which is a decl-specifier within a
simple-declaration. No declarator in sight. :-)

Or am I missing something?

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

Back to top
Ben Hutchings
Guest





PostPosted: Mon Sep 01, 2003 7:10 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

In article <f0648a6e.0308291546.4ca4bff6 (AT) posting (DOT) google.com>, Frank wrote:
Quote:
Thanks for all your responses. All you said are correct. But for some
reason, gcc simply won't compile when I have it like this.

template <int size
class Special_Tree_Node1 : public
Basic_Tree_Node
With a lucky stroke, a space was inserted after sudden, it compiles.

template <int size
class Special_Tree_Node1 : public
Basic_Tree_Node
Is there some rule about the space in defining template parameters?
This is totally nuts.

This is a well known problem: the source is tokenised by finding the
longest possible valid token, and ">>" can be a single token, so it is
interpreted as that rather than as two tokens that are end-brackets.
This is not entirely unreasonable, as you could derive from e.g.
Basic_Tree_Node<Special_Tree_Node11> >.

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

Back to top
Daveed Vandevoorde
Guest





PostPosted: Tue Sep 09, 2003 12:32 pm    Post subject: Re: Creating a template class based on Barton-Nackman trick Reply with quote

[email]johnchx2 (AT) yahoo (DOT) com[/email] (johnchx) wrote:
Quote:
google (AT) vandevoorde (DOT) com (Daveed Vandevoorde) wrote


3.3.6/1: The class scope includes the declarative region
starting after the declaration of the name.

That last part is not entirely clear: I think the text was written
without consideration for implicit declarations. I'll ask for a
Core WG clarification.

3.3.6/1 (1) says:
The potential scope of a name declared in a class consists not only
of the declarative region following the name's declarator....

I don't believe that this can apply to the class name itself because
it has no declarator (thus there is no declarative region following
the name's declarator).

That's what I meant by "not entirely clear". The definition of
class scope does not allow for names declared without a
declarator (including, in this case, implicit declarations).

Surely we meant for E in

struct S {
enum E { e };
// ...
};

to be in the class scope of S. So my guess is that "declarator"
is not the intended term here.

Daveed

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