public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Two-stage name lookup problem
@ 2005-10-26  7:18 Jakub Pawlewicz
  2005-10-26 12:47 ` John Love-Jensen
  2005-10-27 12:22 ` Jakub Pawlewicz
  0 siblings, 2 replies; 9+ messages in thread
From: Jakub Pawlewicz @ 2005-10-26  7:18 UTC (permalink / raw)
  To: gcc-help

I have problem with templates and I need a solution. I want to use
inner class B with a member of outer class A type. Then I wand class A
to use template class B in function f. Here is code I want to change
in order to compile with gcc 3.4. It compiles fine with gcc 3.3.

struct A {
 int x;
 A(int x) : x(x) { }

 template <int X>
 struct B {
   A a;
   B() : a(X) { }
   void f() { }
 };

 template <int X>
 void f()
 {
   B<X> b;
   b.f();
 }
};

int main()
{
 A a(0);
 a.f<0>();
}

Compilation fails with a message
a.cpp:7: error: field `a' has incomplete type
a.cpp: In constructor `A::B<X>::B()':
a.cpp:8: error: class `A::B<X>' does not have any field named `a'

Is there any workaround?

Thanks in advance

Jakub Pawlewicz

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26  7:18 Two-stage name lookup problem Jakub Pawlewicz
@ 2005-10-26 12:47 ` John Love-Jensen
  2005-10-26 14:07   ` Jakub Pawlewicz
  2005-11-05 19:35   ` Nathan Sidwell
  2005-10-27 12:22 ` Jakub Pawlewicz
  1 sibling, 2 replies; 9+ messages in thread
From: John Love-Jensen @ 2005-10-26 12:47 UTC (permalink / raw)
  To: Jakub Pawlewicz, MSX to GCC

Hi Jakub,

Your problem is not with templates.

Here's your problem in a nutshell...

struct A
{
    int x;

    struct B
    {
        A a;
    };
};


You cannot use A within B, because at that point A is incomplete.

You can pull B out of A.  If you want B to be in the A namespace, change
'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
then use that within 'struct B'.

HTH,
--Eljay

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26 12:47 ` John Love-Jensen
@ 2005-10-26 14:07   ` Jakub Pawlewicz
  2005-10-26 14:43     ` corey taylor
  2005-11-05 19:35   ` Nathan Sidwell
  1 sibling, 1 reply; 9+ messages in thread
From: Jakub Pawlewicz @ 2005-10-26 14:07 UTC (permalink / raw)
  To: MSX to GCC

> Your problem is not with templates.
>
> Here's your problem in a nutshell...
>
> struct A
> {
>     int x;
>
>     struct B
>     {
>         A a;
>     };
> };
>
>
> You cannot use A within B, because at that point A is incomplete.
>
> You can pull B out of A.  If you want B to be in the A namespace, change
> 'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
> then use that within 'struct B'.

But what about function f(), the member of struct A? I want to declare
variable with type B in the body of the function:

struct A {
    ...
    void f()
    {
        B b;
        ...
    }
};

I am aware that kind of code may be ill formed, but when using
templates, there should be something like deferred instantiation.
Struct B is a template and also function A::f() is a template. Struct
B is needed only when function A::f() is used. Struct B should be able
to construct member of type A and Struct B do not use function A::f().
I want all functions be inline. Any solutions?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26 14:07   ` Jakub Pawlewicz
@ 2005-10-26 14:43     ` corey taylor
  2005-10-26 15:56       ` Jakub Pawlewicz
  0 siblings, 1 reply; 9+ messages in thread
From: corey taylor @ 2005-10-26 14:43 UTC (permalink / raw)
  To: Jakub Pawlewicz; +Cc: MSX to GCC

Jakub,

  The declaration of A a; in struct B because it requires an object
size.  Using a pointer to an incomplete type is allowed.  You could
create a new A in the B constructor and assign it to a pointer.

  The other errors center around this.  The question about using B b
has nothing to do with the error above.

Corey

On 10/26/05, Jakub Pawlewicz <jakub.pawlewicz@gmail.com> wrote:
> > Your problem is not with templates.
> >
> > Here's your problem in a nutshell...
> >
> > struct A
> > {
> >     int x;
> >
> >     struct B
> >     {
> >         A a;
> >     };
> > };
> >
> >
> > You cannot use A within B, because at that point A is incomplete.
> >
> > You can pull B out of A.  If you want B to be in the A namespace, change
> > 'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
> > then use that within 'struct B'.
>
> But what about function f(), the member of struct A? I want to declare
> variable with type B in the body of the function:
>
> struct A {
>     ...
>     void f()
>     {
>         B b;
>         ...
>     }
> };
>
> I am aware that kind of code may be ill formed, but when using
> templates, there should be something like deferred instantiation.
> Struct B is a template and also function A::f() is a template. Struct
> B is needed only when function A::f() is used. Struct B should be able
> to construct member of type A and Struct B do not use function A::f().
> I want all functions be inline. Any solutions?
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26 14:43     ` corey taylor
@ 2005-10-26 15:56       ` Jakub Pawlewicz
  2005-10-26 16:20         ` corey taylor
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Pawlewicz @ 2005-10-26 15:56 UTC (permalink / raw)
  To: corey taylor; +Cc: MSX to GCC

I'm confused. I do not want use any pointers and memory allocation. I
wrote a program which is very fast because I was using many inline
templates and no pointers. The program worked find unless I had to
switch to gcc 3.4. In my first post it is important that there are
templates and that I am using non-pointer variable declaration of type
B in function A::f(). Please go back to the original problem.

I don't know template terminology, but I try my best to describe what
the problem is. So please be gentle if I make something wrong.

The declaration of A a; in struct B should be allowed if we are able
to postpone instantiation of struct B, because it is a template
struct. The function A::f() is template also, so maybe we could better
postpone the instantiation of the function body. I don't know how can
I do such things. Before two-stage names lookup there was no problem
with such hacks and now I need a workaround..

2005/10/26, corey taylor <corey.taylor@gmail.com>:
> Jakub,
>
>   The declaration of A a; in struct B because it requires an object
> size.  Using a pointer to an incomplete type is allowed.  You could
> create a new A in the B constructor and assign it to a pointer.
>
>   The other errors center around this.  The question about using B b
> has nothing to do with the error above.
>
> Corey
>
> On 10/26/05, Jakub Pawlewicz <jakub.pawlewicz@gmail.com> wrote:
> > > Your problem is not with templates.
> > >
> > > Here's your problem in a nutshell...
> > >
> > > struct A
> > > {
> > >     int x;
> > >
> > >     struct B
> > >     {
> > >         A a;
> > >     };
> > > };
> > >
> > >
> > > You cannot use A within B, because at that point A is incomplete.
> > >
> > > You can pull B out of A.  If you want B to be in the A namespace, change
> > > 'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
> > > then use that within 'struct B'.
> >
> > But what about function f(), the member of struct A? I want to declare
> > variable with type B in the body of the function:
> >
> > struct A {
> >     ...
> >     void f()
> >     {
> >         B b;
> >         ...
> >     }
> > };
> >
> > I am aware that kind of code may be ill formed, but when using
> > templates, there should be something like deferred instantiation.
> > Struct B is a template and also function A::f() is a template. Struct
> > B is needed only when function A::f() is used. Struct B should be able
> > to construct member of type A and Struct B do not use function A::f().
> > I want all functions be inline. Any solutions?
> >
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26 15:56       ` Jakub Pawlewicz
@ 2005-10-26 16:20         ` corey taylor
  0 siblings, 0 replies; 9+ messages in thread
From: corey taylor @ 2005-10-26 16:20 UTC (permalink / raw)
  To: Jakub Pawlewicz; +Cc: MSX to GCC

Jakub,

  I understand your dilemna.  The best thing I can do for you right
now is to show the C++ specification paragraph that rules in the
compiler are generated from:

Knowing which names are type names allows the syntax of every template
definition to be checked. No
diagnostic shall be issued for a template definition for which a valid
specialization can be generated. If no
valid specialization can be generated for a template definition, and
that template is not instantiated, the template
definition is ill-formed, no diagnostic required. If a type used in a
non-dependent name is incomplete
at the point at which a template is defined but is complete at the
point at which an instantiation is done, and
if the completeness of that type affects whether or not the program is
well-formed or affects the semantics
of the program, the program is ill-formed; no diagnostic is required.
[Note: if a template is instantiated,
errors will be diagnosed according to the other rules in this
Standard. Exactly when these errors are diagnosed
is a quality of implementation issue. ] [Example:
int j;
template<class T> class X {
// ...
void f(T t, int i, char* p)
{
t = i; // diagnosed if X::f is instantiated
// and the assignment to t is an error
p = i; // may be diagnosed even if X::f is
// not instantiated
p = j; // may be diagnosed even if X::f is
// not instantiated
}
void g(T t) {
+; //may be diagnosed even if X::g is
// not instantiated
}
};
—end example]

corey

On 10/26/05, Jakub Pawlewicz <jakub.pawlewicz@gmail.com> wrote:
> I'm confused. I do not want use any pointers and memory allocation. I
> wrote a program which is very fast because I was using many inline
> templates and no pointers. The program worked find unless I had to
> switch to gcc 3.4. In my first post it is important that there are
> templates and that I am using non-pointer variable declaration of type
> B in function A::f(). Please go back to the original problem.
>
> I don't know template terminology, but I try my best to describe what
> the problem is. So please be gentle if I make something wrong.
>
> The declaration of A a; in struct B should be allowed if we are able
> to postpone instantiation of struct B, because it is a template
> struct. The function A::f() is template also, so maybe we could better
> postpone the instantiation of the function body. I don't know how can
> I do such things. Before two-stage names lookup there was no problem
> with such hacks and now I need a workaround..
>
> 2005/10/26, corey taylor <corey.taylor@gmail.com>:
> > Jakub,
> >
> >   The declaration of A a; in struct B because it requires an object
> > size.  Using a pointer to an incomplete type is allowed.  You could
> > create a new A in the B constructor and assign it to a pointer.
> >
> >   The other errors center around this.  The question about using B b
> > has nothing to do with the error above.
> >
> > Corey
> >
> > On 10/26/05, Jakub Pawlewicz <jakub.pawlewicz@gmail.com> wrote:
> > > > Your problem is not with templates.
> > > >
> > > > Here's your problem in a nutshell...
> > > >
> > > > struct A
> > > > {
> > > >     int x;
> > > >
> > > >     struct B
> > > >     {
> > > >         A a;
> > > >     };
> > > > };
> > > >
> > > >
> > > > You cannot use A within B, because at that point A is incomplete.
> > > >
> > > > You can pull B out of A.  If you want B to be in the A namespace, change
> > > > 'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
> > > > then use that within 'struct B'.
> > >
> > > But what about function f(), the member of struct A? I want to declare
> > > variable with type B in the body of the function:
> > >
> > > struct A {
> > >     ...
> > >     void f()
> > >     {
> > >         B b;
> > >         ...
> > >     }
> > > };
> > >
> > > I am aware that kind of code may be ill formed, but when using
> > > templates, there should be something like deferred instantiation.
> > > Struct B is a template and also function A::f() is a template. Struct
> > > B is needed only when function A::f() is used. Struct B should be able
> > > to construct member of type A and Struct B do not use function A::f().
> > > I want all functions be inline. Any solutions?
> > >
> >
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26  7:18 Two-stage name lookup problem Jakub Pawlewicz
  2005-10-26 12:47 ` John Love-Jensen
@ 2005-10-27 12:22 ` Jakub Pawlewicz
  1 sibling, 0 replies; 9+ messages in thread
From: Jakub Pawlewicz @ 2005-10-27 12:22 UTC (permalink / raw)
  To: gcc-help

I found a workaround. It looks ugly, but it works. I used dummy
template arguments to overcome instantiation. I hope somebody will
find a nicer solution. Here is a hacked code:

template <typename Dummy> struct A_impl;

typedef A_impl<void> A;

template <typename Dummy>
struct A_impl {
 int x;
 A_impl(int x) : x(x) { }

  template <int X, typename Dummy2>
  struct B {
    A_impl<Dummy2> a;
    B() : a(X) { }
    void f() { }
  };

  template <int X>
   void f()
   {
     B<X, Dummy> b;
     b.f();
   }
};

int main()
{
  A a(0);
  a.f<0>();
}


2005/10/26, Jakub Pawlewicz <jakub.pawlewicz@gmail.com>:
> I have problem with templates and I need a solution. I want to use
> inner class B with a member of outer class A type. Then I wand class A
> to use template class B in function f. Here is code I want to change
> in order to compile with gcc 3.4. It compiles fine with gcc 3.3.
>
> struct A {
>  int x;
>  A(int x) : x(x) { }
>
>  template <int X>
>  struct B {
>    A a;
>    B() : a(X) { }
>    void f() { }
>  };
>
>  template <int X>
>  void f()
>  {
>    B<X> b;
>    b.f();
>  }
> };
>
> int main()
> {
>  A a(0);
>  a.f<0>();
> }
>
> Compilation fails with a message
> a.cpp:7: error: field `a' has incomplete type
> a.cpp: In constructor `A::B<X>::B()':
> a.cpp:8: error: class `A::B<X>' does not have any field named `a'
>
> Is there any workaround?
>
> Thanks in advance
>
> Jakub Pawlewicz
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
  2005-10-26 12:47 ` John Love-Jensen
  2005-10-26 14:07   ` Jakub Pawlewicz
@ 2005-11-05 19:35   ` Nathan Sidwell
  1 sibling, 0 replies; 9+ messages in thread
From: Nathan Sidwell @ 2005-11-05 19:35 UTC (permalink / raw)
  To: John Love-Jensen; +Cc: Jakub Pawlewicz, MSX to GCC

John Love-Jensen wrote:
> Hi Jakub,
> 
> Your problem is not with templates.
> 
> Here's your problem in a nutshell...
> 
> struct A
> {
>     int x;
> 
>     struct B
>     {
>         A a;
>     };
> };

write this as
struct A { int x; struct B;};
struct A::B { A a;};

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Two-stage name lookup problem
@ 2005-10-26 13:57 Brian T. Brunner
  0 siblings, 0 replies; 9+ messages in thread
From: Brian T. Brunner @ 2005-10-26 13:57 UTC (permalink / raw)
  To: gcc-help


The a of type A contains a B, which includes another a of type A which in turn includes a B...
I can't imagine this not being an infinite recursion at the data object creation level.

If B contains a pointer to an object of type A, then we should be OK.

Brian Brunner
brian.t.brunner@gai-tronics.com
(610)796-5838

>>> John Love-Jensen <eljay@adobe.com> 10/26/05 08:47AM >>>
Hi Jakub,

Your problem is not with templates.

Here's your problem in a nutshell...

struct A
{
    int x;

    struct B
    {
        A a;
    };
};


You cannot use A within B, because at that point A is incomplete.

You can pull B out of A.  If you want B to be in the A namespace, change
'struct A' to 'namespace A', and make 'struct A_impl', fully declared, and
then use that within 'struct B'.

HTH,
--Eljay


*******************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept
for the presence of computer viruses.

www.hubbell.com - Hubbell Incorporated

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2005-11-05 19:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-26  7:18 Two-stage name lookup problem Jakub Pawlewicz
2005-10-26 12:47 ` John Love-Jensen
2005-10-26 14:07   ` Jakub Pawlewicz
2005-10-26 14:43     ` corey taylor
2005-10-26 15:56       ` Jakub Pawlewicz
2005-10-26 16:20         ` corey taylor
2005-11-05 19:35   ` Nathan Sidwell
2005-10-27 12:22 ` Jakub Pawlewicz
2005-10-26 13:57 Brian T. Brunner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).