 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
mlimber Guest
|
Posted: Tue Jul 26, 2005 12:12 am Post subject: Template compiler error |
|
|
The following code is a reduced version of my real code and does not
compile on various platforms (Comeau online, and EDG online at
Dinkumware.com, g++ 3.4.1, TI Code Composer, but not .NET '03 online at
Dinkumware.com or Visual C++ 6). The errors are noted in comments:
template<typename T, typename>
class A
{
public:
void AFunc() const {}
protected:
A() {} // Must be subclassed to be instantiated
T t_;
};
template <typename T>
struct B
{
struct C { int j; };
struct D : public A<int,C>
{
int DFunc()
{
AFunc(); // Error: AFunc undefined!
return t_; // Error: t_ undefined!
}
};
D d_;
};
// Instantiate B
B<int> b;
I can get things to compile by:
1. Putting the compiler in "relaxed" mode in g++ or Comeau,
2. Making C a non-nested class by putting it at namespace/file scope,
3. Changing the template parameters to A (e.g., change a line above to
"struct D : public A<int,int>"), or
4. Making B a non-template class.
Obviously, none of these solutions is ideal. Any suggestions or ideas
why this happens?
M
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hyman Rosen Guest
|
Posted: Tue Jul 26, 2005 6:53 am Post subject: Re: Template compiler error |
|
|
mlimber wrote:
| Quote: | Any suggestions or ideas why this happens?
|
Two-phase name lookup. To fix it, write Dfunc like this:
int Dfunc()
{
A<int,C>::AFunc();
return A<int,C>::t_;
}
But, you ask, where is the dependent name which causes the
delayed lookup? It's in 14.6.1/2d: "Within the scope of a
class template, when the unqualified name of a nested class
of the class template is referred to, it is equivalent to
the name of the nested class qualified by the name of the
enclosing class template." So what you actually have is
template <typename T>
struct B
{
struct C { int j; };
struct D : public A<int, typename B
{
int DFunc()
{
AFunc(); // Error: AFunc undefined!
return t_; // Error: t_ undefined!
}
};
D d_;
};
That makes D's base class a dependent name, and that
triggers the problem, even though it's not possible
for C to be anything but the struct C you've written.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Tue Jul 26, 2005 6:54 am Post subject: Re: Template compiler error |
|
|
mlimber wrote:
[...]
| Quote: | template<typename T, typename
class A
{
public:
void AFunc() const {}
protected:
A() {} // Must be subclassed to be instantiated
T t_;
};
template
struct B
{
struct C { int j; };
struct D : public A
{
int DFunc()
{
AFunc(); // Error: AFunc undefined!
return t_; // Error: t_ undefined!
|
Inside a template definition there are dependent and non-dependent
names (which do or don't depend on the template parameters). AFunc
and t_ in your statements are non-dependent and as such are looked
up when parsing the template definition. You want these names to be
found in the base class A
name and thus A<int,C> is a dependent base of D. The problem is that
dependent bases are not examined for non-dependent names. To solve
the problem make these names dependent. The easiest possibility is
to use "this->":
this->AFunc();
return this->t_;
The other possibility is explicit qualification:
A<int,C>::AFunc();
return A<int,C>::t_;
| Quote: | }
};
D d_;
};
[...] |
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ganny Guest
|
Posted: Tue Jul 26, 2005 6:55 am Post subject: Re: Template compiler error |
|
|
The name in template base class is not visible according to the
Standard lookup rules (See [temp.dep], 14.6.2(3) ). You can make it
visible by adding this before AFunc and t_.
-Ganesh.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mlimber Guest
|
Posted: Wed Jul 27, 2005 3:17 pm Post subject: Re: Template compiler error |
|
|
Hyman Rosen wrote:
[snip]
| Quote: | But, you ask, where is the dependent name which causes the
delayed lookup? It's in 14.6.1/2d: "Within the scope of a
class template, when the unqualified name of a nested class
of the class template is referred to, it is equivalent to
the name of the nested class qualified by the name of the
enclosing class template." So what you actually have is
[snip]
That makes D's base class a dependent name, and that
triggers the problem, even though it's not possible
for C to be anything but the struct C you've written.
|
Thanks to you and all who answered. That helps. (I forgot to mention
that explicitly qualifying the inherited members also allows the code
to compile. While that's not an unacceptable solution from a design
perspective, it was aesthetically displeasing in the real context.)
A follow-up question: This two-stage name lookup is likely there for a
good reason. Just for edification, can someone give me an example or
two where the rule helps rather than hinders?
Cheers!
M
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|