C++ puzzle - how to get this to compile ?

O

OSS542

How might one go about getting something like the following example to
compile successfully ?

class cls2
{
friend void cls1::fun1();
};
class cls1
{
cls2 mbr1;
public:
void fun1();
};
 
B

Bart v Ingen Schenau

OSS542 said:
How might one go about getting something like the following
example to compile successfully ?

class cls2
{
friend void cls1::fun1();
};
class cls1
{
cls2 mbr1;
public:
void fun1();
};

As is, you can't.
When processing cls2, the compiler does not yet know there is a cls1 with a
member function fun1, so the friend declaration is ill-formed.
And you can not move the definition of cls1 to before cl2 due to the member
object mbr1.

The following rewrites are possible to make it compile:
<code 1>
// Make the entire cls1 class a friend of cls2
class cls1;
class cls2
{
friend class cls1;
};
class cls1
{
cls2 mbr1;
public:
void fun1();
};
</code 1>

<code 2>
// Use a pointer for the member in cls1
class cls2;
class cls1
{
cls2* mbr1;
public:
void fun1();
};
class cls2
{
friend void cls1::fun1();
};
</code 2>

Bart v Ingen Schenau
 
J

Juha Nieminen

OSS542 said:
class cls2
{
friend void cls1::fun1();
};
class cls1
{
cls2 mbr1;
public:
void fun1();
};

In principle there's no technical reason why that couldn't be done. It's
just a question of lacking syntax in the language.

It would be useful if one could, somehow, declare member functions before
the class definition is known. (If the class then fails to define the
declared member function, a linker error would happen.) This can be done
with namespaces, but not with classes.

I'd say a syntax like this would be enough:

class A;
int A::foo(int, int);

Anyone see any problem with that?
 
V

Victor Bazarov

In principle there's no technical reason why that couldn't be done. It's
just a question of lacking syntax in the language.

It would be useful if one could, somehow, declare member functions before
the class definition is known. (If the class then fails to define the
declared member function, a linker error would happen.) This can be done
with namespaces, but not with classes.

I'd say a syntax like this would be enough:

class A;
int A::foo(int, int);

Anyone see any problem with that?

I think you're advocating forward-declaration of member functions. In
that case the full qualification should be allowed for forward-declaring
static, virtual, default, pure virtual and const members of the class.
Basically there shouldn't be a problem if you want to write

virtual int A::foo(int,int) const = 0;

outside the class itself. However, currently the grammar does not allow
the keyword 'virtual' to be used outside a class definition, and also
defines a different meaning of the keyword 'static'.

I don't see "any problem" except that the grammar needs to be made even
more complicated to allow out-of-the-class-definition member declarations.

V
 
J

Juha Nieminen

Victor Bazarov said:
I think you're advocating forward-declaration of member functions. In
that case the full qualification should be allowed for forward-declaring
static, virtual, default, pure virtual and const members of the class.
Basically there shouldn't be a problem if you want to write

virtual int A::foo(int,int) const = 0;

outside the class itself. However, currently the grammar does not allow
the keyword 'virtual' to be used outside a class definition, and also
defines a different meaning of the keyword 'static'.

I don't see "any problem" except that the grammar needs to be made even
more complicated to allow out-of-the-class-definition member declarations.

Perhaps if there was a way to do a kind of "partial declaration" of a
class. In other words, you declare a class and some of its member functions
(and other stuff, such as member types and variables), but it's still not
a full class declaration (iow. you still can't instantiate the class
based solely on this partial declaration).

I don't have a good idea for a syntax for this. I get the feeling that
the standardization committee abhors the addition of new reserved keywords
(in order to, I suppose, minimize name collisions with existing code), and
none of the existing reserved keywords that I can think of sound like a
good fit for this. Perhaps the least horrible keyword I can think of
would be 'namespace'. It could go something like this:

namespace class A // partial declaration of A
{
public:
virtual int foo(int, int) const = 0;
int bar(int);
int bar(int) const;
class InnerClass;
};

Now it would be possible to refer to those member functions and types of
the class A (and even call them using a reference/pointer of type A) before
we have a full definition.
 
O

OSS542

My sincere thanks to Mr v Ingen Schenau and the rest of you for all
your very kind assistance and a most interesting discussion.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top