473,387 Members | 3,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Template related question

The following code - from "C++ Templates: The Complete Guide" by
Vandevoorde/Josuttis - seems to compile with Borland C++. However it
fails to compile with other compilers - Comeau Online and g++. Any
idea why?

template<typename T>
class Shell {
public:
template<int N>
class In {
public:
template<int M>
class Deep {
public:
virtual void f(){}
};
};
};

template<typename T, int N>
class Weird {
public:
void case1(Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(Shell<T>::template In<T>::template Deep<T>& p) {
p.template Deep<N>::f(); // inhibit virtual call
}
};
Thank you.
Jul 22 '05 #1
14 1615
On 8 Apr 2004 15:42:21 -0700, lr******@yahoo.co.in (LRS Kumar) wrote:
The following code - from "C++ Templates: The Complete Guide" by
Vandevoorde/Josuttis - seems to compile with Borland C++. However it
fails to compile with other compilers - Comeau Online and g++. Any
idea why?

template<typename T>
class Shell {
public:
template<int N>
class In {
public:
template<int M>
class Deep {
public:
virtual void f(){}
};
};
};

template<typename T, int N>
class Weird {
public:
void case1(Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(Shell<T>::template In<T>::template Deep<T>& p) {
p.template Deep<N>::f(); // inhibit virtual call
}
};

This is actually in the errata for the book (which I only discovered after
figuring it all out for myself, and then turning to page 132 in the book,
only to find the errata I had forgotten I'd penciled in...)

That last section is supposed to say:
void case1(template Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(template Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2
On 8 Apr 2004 15:42:21 -0700, lr******@yahoo.co.in (LRS Kumar) wrote:
The following code - from "C++ Templates: The Complete Guide" by
Vandevoorde/Josuttis - seems to compile with Borland C++. However it
fails to compile with other compilers - Comeau Online and g++. Any
idea why?

template<typename T>
class Shell {
public:
template<int N>
class In {
public:
template<int M>
class Deep {
public:
virtual void f(){}
};
};
};

template<typename T, int N>
class Weird {
public:
void case1(Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(Shell<T>::template In<T>::template Deep<T>& p) {
p.template Deep<N>::f(); // inhibit virtual call
}
};

This is actually in the errata for the book (which I only discovered after
figuring it all out for myself, and then turning to page 132 in the book,
only to find the errata I had forgotten I'd penciled in...)

That last section is supposed to say:
void case1(template Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(template Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #3
On Thu, 08 Apr 2004 23:39:04 GMT, Leor Zolman <le**@bdsoft.com> wrote:

Darn! I MEANT:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #4
On Thu, 08 Apr 2004 23:39:04 GMT, Leor Zolman <le**@bdsoft.com> wrote:

Darn! I MEANT:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #5

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:9f********************************@4ax.com...
On 8 Apr 2004 15:42:21 -0700, lr******@yahoo.co.in (LRS Kumar) wrote:
This is actually in the errata for the book (which I only discovered after
figuring it all out for myself, and then turning to page 132 in the book,
only to find the errata I had forgotten I'd penciled in...)

That last section is supposed to say:
void case1(template Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(template Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


template<typename T, int N>
class Weird {
public:
void case1 (typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2 (typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call
}
};
Regards,
Sumit.
Jul 22 '05 #6

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:9f********************************@4ax.com...
On 8 Apr 2004 15:42:21 -0700, lr******@yahoo.co.in (LRS Kumar) wrote:
This is actually in the errata for the book (which I only discovered after
figuring it all out for myself, and then turning to page 132 in the book,
only to find the errata I had forgotten I'd penciled in...)

That last section is supposed to say:
void case1(template Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(template Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


template<typename T, int N>
class Weird {
public:
void case1 (typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2 (typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call
}
};
Regards,
Sumit.
Jul 22 '05 #7
lr******@yahoo.co.in (LRS Kumar) wrote:
[...]
template<typename T, int N>
class Weird {
public:
void case1(Shell<T>::template In<N>::template Deep<N>* p) { ^ insert "typename " here p->template Deep<N>::f(); // inhibit virtual call
}
void case2(Shell<T>::template In<T>::template Deep<T>& p) { ^ insert "typename " here p.template Deep<N>::f(); // inhibit virtual call
}
};


There are two "typename " keywords missing.

My apologies for the error.

This particular one was fixed in the 2nd print.
You can see a list of known issues at
http://www.josuttis.com/tmplbook/errata.html

Daveed
Jul 22 '05 #8
lr******@yahoo.co.in (LRS Kumar) wrote:
[...]
template<typename T, int N>
class Weird {
public:
void case1(Shell<T>::template In<N>::template Deep<N>* p) { ^ insert "typename " here p->template Deep<N>::f(); // inhibit virtual call
}
void case2(Shell<T>::template In<T>::template Deep<T>& p) { ^ insert "typename " here p.template Deep<N>::f(); // inhibit virtual call
}
};


There are two "typename " keywords missing.

My apologies for the error.

This particular one was fixed in the 2nd print.
You can see a list of known issues at
http://www.josuttis.com/tmplbook/errata.html

Daveed
Jul 22 '05 #9
Even that didn't compile for me on g++ 3.3.1
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();" have
both had the template keyword removed

Makes sense too, since the template keyword is used to declare templates. We
have already made it known that p in case 1 is a pointer to an object of
type Shell<T>::template In<N>::template Deep<N>. When we use p to access
methods from the interface of an object of that type, I suppose using the
keyword "template" must be an error

(Sorry for hitting "Reply" and not "Reply Group" on that last post)

Regards,
Vikram

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ln********************************@4ax.com...
On Thu, 08 Apr 2004 23:39:04 GMT, Leor Zolman <le**@bdsoft.com> wrote:

Darn! I MEANT:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html

Jul 22 '05 #10
Even that didn't compile for me on g++ 3.3.1
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();" have
both had the template keyword removed

Makes sense too, since the template keyword is used to declare templates. We
have already made it known that p in case 1 is a pointer to an object of
type Shell<T>::template In<N>::template Deep<N>. When we use p to access
methods from the interface of an object of that type, I suppose using the
keyword "template" must be an error

(Sorry for hitting "Reply" and not "Reply Group" on that last post)

Regards,
Vikram

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ln********************************@4ax.com...
On Thu, 08 Apr 2004 23:39:04 GMT, Leor Zolman <le**@bdsoft.com> wrote:

Darn! I MEANT:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->template Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.template Deep<N>::f(); // inhibit virtual call


-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html

Jul 22 '05 #11
On Fri, 09 Apr 2004 14:36:52 GMT, "Vikram Paranjape"
<us***********@spamgourmet.com> wrote:
Even that didn't compile for me on g++ 3.3.1 Probably a gcc bug.
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();" have
both had the template keyword removed


Clearly, then, gcc has trouble with the "template" keyword. It compiles
without error using Comeau, MSVC 7 and 7.1, Borland (even free command
line tools), CodeWarrior 8, and Digital Mars.
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #12
Vikram Paranjape wrote in
news:8y********************@twister.southeast.rr.c om:
Even that didn't compile for me on g++ 3.3.1
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p)
{
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p)
{
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();"
have both had the template keyword removed

Makes sense too, since the template keyword is used to declare
templates. We have already made it known that p in case 1 is a pointer
to an object of type Shell<T>::template In<N>::template Deep<N>. When
we use p to access methods from the interface of an object of that
type, I suppose using the keyword "template" must be an error


Makes sence to us maybe, however g++ is wrong here, this shows why:

struct X
{
int Deep;
};

int f() { return 3; }

template<typename T>
class Shell
{
public:
template<int N>
class In
{
public:
template<int M>
class Deep : public X
{
public:
virtual void f(){}
};
};
};

template<typename T, int N>
class Weird
{
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p)
{
p->Deep<N>::f(); // inhibit virtual call
}

void case2(typename Shell<T>::template In<N>::template Deep<N>& p)
{
p.Deep<N>::f(); // inhibit virtual call
}
};
int main()
{
Weird< int, 3 > w;
Shell< int >::In< 3 >::Deep< 3 > arg;

w.case1( & arg );
w.case2( arg );
}

Both VC 7.1 and CBuilderX (preview) compile the above, the programme
does exhibit UB, but thats only 'cause I didn't bother to initialize
X::Deep.;)

If you put the template back into p.Deep<N>::f(), CBuilderX still
compiles (*), VC and g++ (3.2 and 3.4 (prerelease **)) all fail to
compile.

*) I think it should, but I wouldn't bet on it, also I don't
really care as the above (modified) code is mostly nonsence.

**) The gcc 3.4 prerelease is quite old now, a later version may
behave differently.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #13
On Fri, 09 Apr 2004 14:36:52 GMT, "Vikram Paranjape"
<us***********@spamgourmet.com> wrote:
Even that didn't compile for me on g++ 3.3.1 Probably a gcc bug.
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();" have
both had the template keyword removed


Clearly, then, gcc has trouble with the "template" keyword. It compiles
without error using Comeau, MSVC 7 and 7.1, Borland (even free command
line tools), CodeWarrior 8, and Digital Mars.
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #14
Vikram Paranjape wrote in
news:8y********************@twister.southeast.rr.c om:
Even that didn't compile for me on g++ 3.3.1
Here's what I had to change it to:

template<typename T, int N>
class Weird {
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p)
{
p->Deep<N>::f(); // inhibit virtual call
}
void case2(typename Shell<T>::template In<N>::template Deep<N>& p)
{
p.Deep<N>::f(); // inhibit virtual call
}
};

Note that "p->template Deep<N>::f();" and "p.template Deep<N>::f();"
have both had the template keyword removed

Makes sense too, since the template keyword is used to declare
templates. We have already made it known that p in case 1 is a pointer
to an object of type Shell<T>::template In<N>::template Deep<N>. When
we use p to access methods from the interface of an object of that
type, I suppose using the keyword "template" must be an error


Makes sence to us maybe, however g++ is wrong here, this shows why:

struct X
{
int Deep;
};

int f() { return 3; }

template<typename T>
class Shell
{
public:
template<int N>
class In
{
public:
template<int M>
class Deep : public X
{
public:
virtual void f(){}
};
};
};

template<typename T, int N>
class Weird
{
public:
void case1(typename Shell<T>::template In<N>::template Deep<N>* p)
{
p->Deep<N>::f(); // inhibit virtual call
}

void case2(typename Shell<T>::template In<N>::template Deep<N>& p)
{
p.Deep<N>::f(); // inhibit virtual call
}
};
int main()
{
Weird< int, 3 > w;
Shell< int >::In< 3 >::Deep< 3 > arg;

w.case1( & arg );
w.case2( arg );
}

Both VC 7.1 and CBuilderX (preview) compile the above, the programme
does exhibit UB, but thats only 'cause I didn't bother to initialize
X::Deep.;)

If you put the template back into p.Deep<N>::f(), CBuilderX still
compiles (*), VC and g++ (3.2 and 3.4 (prerelease **)) all fail to
compile.

*) I think it should, but I wouldn't bet on it, also I don't
really care as the above (modified) code is mostly nonsence.

**) The gcc 3.4 prerelease is quite old now, a later version may
behave differently.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: wogston | last post by:
A) template <typename scalar, int size> struct basevector { enum { size = size }; scalar v; }; B)
31
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will...
7
by: Siemel Naran | last post by:
Hi. I have a function template <class InputIter, class OutputIter> void f(InputIter begin, InputIter end, OutputIter result); With c of type char* and cc of type const char*, the code...
3
by: bonj | last post by:
Hello How do I declare a template class such that the template class T must implement a certain interface? e.g. interface IProvideID { int MyID; };
5
by: Amit | last post by:
Greetings all, I am writing some code somehwat similar to the test code I have below. I am having a variety of issues with template specialization. I am not sure if this is related to something...
2
by: coolpint | last post by:
Can anyone kindly provide an explanation as to why the compiler does not "see" the function template in the contrieved code below? I think the argument deduction fails but can't figure out...
2
by: toton | last post by:
Hi, This is a silly question related to syntax only. I have a template class with template member function, How to write it separately in a file (not translation unit, just want to separate...
272
by: Peter Olcott | last post by:
http://groups.google.com/group/comp.lang.c++/msg/a9092f0f6c9bf13a I think that the operator() member function does not work correctly, does anyone else know how to make a template for making two...
6
by: subramanian100in | last post by:
consider the following program: #include <iostream> #include <cstdlib> using namespace std; template<typename Tvoid fcn(T arg) { cout << "from fcn(T arg)" << endl;
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.