473,396 Members | 1,773 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,396 software developers and data experts.

Problem with template using base class template in GCC

The following gives an error in the declaration of the
member function x() of the class template Tpl, compiliing
with a recent version of GCC under Solaris:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX<AOrB>()); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(void);
};

template<>
inline int TheBase::baseX<A>(void) { return(1); }

template<>
inline int TheBase::baseX<B>(void) { return(2); }

Tpl<TheBase> aTpl;

But if I give 'baseX' a dummy parameter whose type is the type parameter
to the template, making explicit naming of the type paramenter in the
baseX call unecessary, it does compile:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX(AOrB())); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(AOrB aOrB);
};

template<>
inline int TheBase::baseX<A>(A a) { return(1); }

template<>
inline int TheBase::baseX<B>(B b) { return(2); }

Tpl<TheBase> aTpl;

Is there some rule in the standard that requires this behavior?
Or is this just a problem with the GCC compiler?

Another thing that surprised me was that GCC gives me an error if
I put the partial specializations of 'baseX' inside the declaration
of the class 'TheBase'.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #1
13 2786
"Walt Karas" <wk****@yahoo.com> wrote...
The following gives an error in the declaration of the
member function x() of the class template Tpl, compiliing
with a recent version of GCC under Solaris:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX<AOrB>()); }
I got it to compile by doing this:

template <typename AOrB>
inx x() { return this->template baseX<AOrB>(); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(void);
};

template<>
inline int TheBase::baseX<A>(void) { return(1); }

template<>
inline int TheBase::baseX<B>(void) { return(2); }

Tpl<TheBase> aTpl;

But if I give 'baseX' a dummy parameter whose type is the type parameter
to the template, making explicit naming of the type paramenter in the
baseX call unecessary, it does compile:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX(AOrB())); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(AOrB aOrB);
};

template<>
inline int TheBase::baseX<A>(A a) { return(1); }

template<>
inline int TheBase::baseX<B>(B b) { return(2); }

Tpl<TheBase> aTpl;

Is there some rule in the standard that requires this behavior?
Yes, if the base class depends on the template type, its scope is not
searched to resolve a dependent name.
Or is this just a problem with the GCC compiler?
I don't think so. Comeau also rejected the first example.
Another thing that surprised me was that GCC gives me an error if
I put the partial specializations of 'baseX' inside the declaration
of the class 'TheBase'.


That's also still prohibited. They are thinking of adding it to the
next Standard, IIRC.

V
Jul 22 '05 #2
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<81yXc.316605$a24.50596@attbi_s03>...
"Walt Karas" <wk****@yahoo.com> wrote...
The following gives an error in the declaration of the
member function x() of the class template Tpl, compiliing
with a recent version of GCC under Solaris:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX<AOrB>()); }


I got it to compile by doing this:

template <typename AOrB>
inx x() { return this->template baseX<AOrB>(); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(void);
};

template<>
inline int TheBase::baseX<A>(void) { return(1); }

template<>
inline int TheBase::baseX<B>(void) { return(2); }

Tpl<TheBase> aTpl;

But if I give 'baseX' a dummy parameter whose type is the type parameter
to the template, making explicit naming of the type paramenter in the
baseX call unecessary, it does compile:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX(AOrB())); }
};

class TheBase
{
public:

template<typename AOrB>
int baseX(AOrB aOrB);
};

template<>
inline int TheBase::baseX<A>(A a) { return(1); }

template<>
inline int TheBase::baseX<B>(B b) { return(2); }

Tpl<TheBase> aTpl;

Is there some rule in the standard that requires this behavior?


Yes, if the base class depends on the template type, its scope is not
searched to resolve a dependent name.
Or is this just a problem with the GCC compiler?


I don't think so. Comeau also rejected the first example.
Another thing that surprised me was that GCC gives me an error if
I put the partial specializations of 'baseX' inside the declaration
of the class 'TheBase'.


That's also still prohibited. They are thinking of adding it to the
next Standard, IIRC.

V


Firstly I'd like to say that it compiles ok with MS 2003 Compiler.

I believe it should compile ok as I can see nothing wrong with the
code.
But the point made about name lookup , I have read too that base
templates are not searched but in this case we have the rules of
inheritance do we not. You could also try to call the base funtion
with fully qualified name which also worked for me but was not
required i.e: theBase::baseX<T>(T b);.
Try making your inheritance public then you should be able to call
baseX directly from instances of Tpl.
I don't think it would be very good if templating a class meant we
lost the inheritance, so I believe it's a fault with your compiler.

And also you are speaking of partial specialization but this is not
partial specialization it's full specialization of member function
baseX. I'm not sure on all the rules but I can define them within the
class and it works fine. And I don't see why you shouldn't be able too
do so. I think member function specializations are generally defined
out of class for clarity though.

HTH Paul
Jul 22 '05 #3
Paul wrote:
[...]
Firstly I'd like to say that it compiles ok with MS 2003 Compiler.

[...]
I'm not sure on all the rules but I can define them within the
class and it works fine. [...]


Have you tried turning "language extensions" off?

Here is the rule of comp.lang.c++: if it compiles with your compiler,
it's not enough to confirm that the code is standard C++. Try to
follow it. To help you develop a sense of right and wrong WRT C++
language, get a copy of the Standard document.

V
Jul 22 '05 #4
[snip]

Note: My compiler language extensions are turned off.
HTH
Paul
Jul 22 '05 #5
Victor Bazarov <v.********@comAcast.net> wrote in message news:<gY**************@newsread1.dllstx09.us.to.ve rio.net>...
Paul wrote:
[...]
Firstly I'd like to say that it compiles ok with MS 2003 Compiler.

[...]
> I'm not sure on all the rules but I can define them within the
class and it works fine. [...]


Have you tried turning "language extensions" off?

Here is the rule of comp.lang.c++: if it compiles with your compiler,
it's not enough to confirm that the code is standard C++. Try to
follow it. To help you develop a sense of right and wrong WRT C++
language, get a copy of the Standard document.

V


Another good rule would be to cite a particular paragraph in
the standard when saying that something isn't compliant, if
at all possible.

Why would it be desirable to impose this limitation? Does
the compiler need to bind the referenced template to a definition
visible in the scope where the refering template is being
defined (in order to make instantiation context-independent)?
Seems like the compiler could just assume the template was
in the base class, then enforce this assumption at
instantiation. Or, if that's too hard, require the previously
posted suggestion of a base:: qualifier on the template.
Jul 22 '05 #6
wk****@yahoo.com (Walt Karas) wrote in message news:<c6**************************@posting.google. com>...
Victor Bazarov <v.********@comAcast.net> wrote in message news:<gY**************@newsread1.dllstx09.us.to.ve rio.net>...
Paul wrote:
[...]
Firstly I'd like to say that it compiles ok with MS 2003 Compiler.

[...]
> I'm not sure on all the rules but I can define them within the
class and it works fine. [...]


Have you tried turning "language extensions" off?

Here is the rule of comp.lang.c++: if it compiles with your compiler,
it's not enough to confirm that the code is standard C++. Try to
follow it. To help you develop a sense of right and wrong WRT C++
language, get a copy of the Standard document.

V


Another good rule would be to cite a particular paragraph in
the standard when saying that something isn't compliant, if
at all possible.

Why would it be desirable to impose this limitation? Does
the compiler need to bind the referenced template to a definition
visible in the scope where the refering template is being
defined (in order to make instantiation context-independent)?
Seems like the compiler could just assume the template was
in the base class, then enforce this assumption at
instantiation. Or, if that's too hard, require the previously
posted suggestion of a base:: qualifier on the template.


I needed to use qualified names with extensions turned off i.e:

return this->baseX<AOrB>();
return Base::baseX<AOrB>();

Both these work for me but I'm still unsure if the second is completely correct.
Here is a link about it:
http://www.tempest-sw.com/cpp/draft/ch07-templates.html
Near the bottom of the page it's explained under Resolving names.

Paul.
Jul 22 '05 #7
Walt Karas wrote:
The following gives an error in the declaration of the
member function x() of the class template Tpl, compiliing
with a recent version of GCC under Solaris:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX<AOrB>()); } ^^^^^^^^^^^^^^^^^^^^^^
(See below) };

class TheBase
{
public:

template<typename AOrB>
int baseX(void);
};

template<>
inline int TheBase::baseX<A>(void) { return(1); }

template<>
inline int TheBase::baseX<B>(void) { return(2); }

Tpl<TheBase> aTpl;


[snip]

I have had to change quite a lot of code of this kind to compile with
gcc-3.4. According to gcc-3.4, the syntax for your call in int Tpl::x() to
a method in the templated base class is:

int x(void) { return(Base::baseX<A0rB>()); }
^^^^^^
In other words, you need to specify that baseX() is a member of the
templated base class. Whether that is required by the standard I know not,
but I expect it is right. gcc-3.4 is a lot stricter than gcc-3.2/3.3.

You have set follow-ups to a group I do not read, so I will not see any
response (not a very good idea).

Chris.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #8
template<>
inline int TheBase::baseX<A>(void) { return(1); }

template<>
inline int TheBase::baseX<B>(void) { return(2); }

Tpl<TheBase> aTpl;

But if I give 'baseX' a dummy parameter whose type is the type parameter
to the template, making explicit naming of the type paramenter in the
baseX call unecessary, it does compile:
Well, I'm not sure to understand what you want to do here ????
But, from what you wrote, I guess that the compiler interpret the two
specialized functions as two more functions in the class TheBase.
Unfortunately, you don't explicitely make use of either class A or
either class B,so the compiler can't decide wich one to choose.

class TheBase
{
public:

template<typename AOrB>
int baseX(AOrB aOrB);
};

template<>
inline int TheBase::baseX<A>(A a) { return(1); }

template<>
inline int TheBase::baseX<B>(B b) { return(2); }

Tpl<TheBase> aTpl;

Here, as you provide two functions with different input arguments,
compiler can now assign two functions to TheBase that are :
int TheBase::baseX(A a);
int TheBase::baseX(B b);

This is a common overloading rule. Remember, you can't overload function
with the same argument.
Another thing that surprised me was that GCC gives me an error if
I put the partial specializations of 'baseX' inside the declaration
of the class 'TheBase'.


Because of c++ doesn't allow template specializations inside a class ...
More exactly specialized template should be associated with a namespace
scope.

Hope, all this will help !
Probably if you tell more about what you want to do exactly, I should help
you a bit more.

Best regards,
Gilles Rochefort



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #9
<snip>

Because of c++ doesn't allow template specializations inside a class ...
More exactly specialized template should be associated with a namespace
scope.


Are you sure about that?

class Test{
public:
template<typename T>void foo(T){}
template<>void foo(double){}
};

The above compiles ok , not saying that means it's right, but are you
ssaying this is not allowed? Is the namespace for foo here not Test?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #10
"Paul" <in***********@hotmail.com> wrote...
<snip>

Because of c++ doesn't allow template specializations inside a class ...
More exactly specialized template should be associated with a namespace
scope.


Are you sure about that?

class Test{
public:
template<typename T>void foo(T){}
template<>void foo(double){}
};

The above compiles ok , not saying that means it's right, but are you
ssaying this is not allowed? Is the namespace for foo here not Test?


How many times do we have to write, "'compiles ok', doesn't necessarily
mean 'correct code'"? Try to remember that and avoid "hey, it compiles
OK on my compiler so it must be good code".
Jul 22 '05 #11
"Victor Bazarov" <v.********@comAcast.net> wrote:
"Walt Karas" <wk****@yahoo.com> wrote...
The following gives an error in the declaration of the
member function x() of the class template Tpl, compiliing
with a recent version of GCC under Solaris:

class A { };
class B { };

template <typename Base>
class Tpl : protected Base
{
public:
template <typename AOrB>
int x(void) { return(baseX<AOrB>()); }


I got it to compile by doing this:

template <typename AOrB>
inx x() { return this->template baseX<AOrB>(); }


To elaborate: firstly, baseX is a dependent name because it
depends on 'Base'. The compiler doesn't look in dependent
base classes to resolve names. So you have go this-> or Base::
to tell the compiler where it is.

Secondly, it doesn't know what the symbol 'baseX' is at this
point. In particular it could be : int baseX; in which case
baseX<AOrB> is parsed as baseX (less-than operator) AOrB
(syntax error). So the keyword 'template' indicates that
baseX is the name of a template member function.
Jul 22 '05 #12

class Test{
public:
template<typename T>void foo(T){}
template<>void foo(double){}
};


Yes, as I said this not allowed ...
The above code don't compile on a recent gcc ( I tested on a 3.3.2 )
I guess that gcc becomes lesser and lesser permissive ..

So, now you have to write the following code to get a chance to compile.

class Test{
public:
template<typename T>void foo(T){}
};

template<>void Test::foo(double){}

Gilles.


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

"Paul" <in***********@hotmail.com> wrote in message
news:1f**************************@posting.google.c om...
<snip>

Because of c++ doesn't allow template specializations inside a class ...
More exactly specialized template should be associated with a namespace
scope.


Are you sure about that?

class Test{
public:
template<typename T>void foo(T){}
template<>void foo(double){}
};


Yes, he is correct. The relevant section in standard is 14.7.3/2: "An
explicit specialization shall be declared in the namespace of which the
template is a member, or, for member templates, in the namespace of which
the enclosing class or enclosing class template is a member."

-Sharad


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

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

Similar topics

4
by: Carsten Spieß | last post by:
Hello all, i have a problem with a template constructor I reduced my code to the following (compiled with gcc 2.7.2) to show my problem: // a base class class Base{}; // two derived...
0
by: okinrus | last post by:
Can someone take a look at this code and figure out why Serializable_base::add_serializer throws std::bad_alloc. The problem seems to be the compiler because msvc++ 7.1 says...
7
by: T.A. | last post by:
Class hierarchy below demonstrates my problem: #include <vector> #include <boost/smart_ptr.hpp> class Fruit { public: virtual ~Fruit() = 0; };
4
by: Grizlyk | last post by:
Hello. Why were base class "typedefs" hidden by template<and explicit usage of them does not work too? Try open only one of the lines in the example below //using Tparent::Tptr; //typedef...
5
by: Wayne Shu | last post by:
Hi, guys I am reading Vandevoorde and Josuttis 's "C++ Template The Complete Guide" these days. When I read the chapter 15: Traits and Policy classes. I copy the code in 15.2.2 that use to...
9
by: Jerome Durand | last post by:
Hello, I'm trying to write something along the following lines but I cannot get this to compile. template <typename derivedstruct Base { typedef typename derived::valueType valueType;...
2
by: syang8 | last post by:
Dear all, I am trying to design classes with stream support. Basically, I want the operator << work for the base class and all the derived classes. If the base class is a template class, and...
2
by: mkvenkit.vc | last post by:
Hello, I hope this is the right place to post a question on Boost. If not, please let me know where I can post this message and I will do so. I am having a strange problem with std::string as...
4
by: StephQ | last post by:
I need to know if it is possible to solve the following problem (I am really stuck at it). Consider the CRTP pattern: struct Derived { ....// May contain void operate( double x ) , may not....
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.