470,855 Members | 1,155 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,855 developers. It's quick & easy.

namespace trouble

Hello all,

I'm rewriting a C++ framework, so that old prefixed names are replaced
by namespaces. Please consider the following class:

=== boundingbox.h ===
[...]
namespace VART {
class Transform; // forward declaration of class Transform
class BoundingBox {
friend std::ostream& operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
void Transform(const Transform& trans);
[...]
===============
1) I tried "class VART::Transform;" before "namespace VART {" which
gave me compile errors. Is the current declaration ok? Is there a
better way?

2) The output operator is inside namespace VART. Could it be outside?
Users of this framework would fell more confortable if it was...

3) I get "boundingbox.h:36: error: declaration of 'void
VART::BoundingBox::Transform(const VART::Transform&)' transform.h:24:
error: changes meaning of 'Transform' from 'class VART::Transform'"
when compiling on g++. I don't see why VART::BoundingBox::Transform
conflicts with VART::Transform. What could be done here?

May 30 '06 #1
11 1908
Bruno de Oliveira Schneider wrote:
Hello all,

I'm rewriting a C++ framework, so that old prefixed names are replaced
by namespaces. Please consider the following class:

=== boundingbox.h ===
[...]
namespace VART {
class Transform; // forward declaration of class Transform
class BoundingBox {
friend std::ostream& operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
void Transform(const Transform& trans);
It is generally a BAD IDEA(tm) to name your functions and your types
the same.
[...]
===============
1) I tried "class VART::Transform;" before "namespace VART {" which
gave me compile errors. Is the current declaration ok? Is there a
better way?
If you have to forward-declare a class in a namespace, you open the
namespace, declare the class, close the namespace. It should be fine.
2) The output operator is inside namespace VART. Could it be outside?
Users of this framework would fell more confortable if it was...
You could prefix it with '::' (meaning in the global namespace).
3) I get "boundingbox.h:36: error: declaration of 'void
VART::BoundingBox::Transform(const VART::Transform&)'
transform.h:24: error: changes meaning of 'Transform' from 'class
VART::Transform'" when compiling on g++. I don't see why
VART::BoundingBox::Transform conflicts with VART::Transform. What
could be done here?


You could (a) rename your function or (b) elaborate the name of the
type:

void Transform(const class Transform&);

But I'd try doing (a) first.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 30 '06 #2
Victor Bazarov wrote:
It is generally a BAD IDEA(tm) to name your functions and your types
the same.
Could you elaborate on that? I really don't see why
VART::BoundingBox::Transform conflicts with VART::Transform.
If you have to forward-declare a class in a namespace, you open the
namespace, declare the class, close the namespace. It should be fine.
Then I guess the way I did (open the namespace once, forward-declare
Transform and declare BoundingBox) is better than opening the namespace
twice (once for forward declarations and then for the class
declaration), right?
You could prefix it with '::' (meaning in the global namespace).


How do I do that? I tried:
=== begin code ===
namespace VART
{
class Transform;
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
=== end code ===
But g++ gives me:
error: 'std::ostream& operator<<(std::ostream&, const
VART::BoundingBox&)' should have been declared inside '::'

May 31 '06 #3
Bruno de Oliveira Schneider wrote:
Victor Bazarov wrote:
It is generally a BAD IDEA(tm) to name your functions and your types
the same.


Could you elaborate on that? I really don't see why
VART::BoundingBox::Transform conflicts with VART::Transform.


If you try referring to 'Transform' inside 'VART::BoundingBox' class,
which 'Transform' would that be? Is that obvious? I am not saying
that you *can't* do that. I am saying that you *shouldn't*.
If you have to forward-declare a class in a namespace, you open the
namespace, declare the class, close the namespace. It should be
fine.


Then I guess the way I did (open the namespace once, forward-declare
Transform and declare BoundingBox) is better than opening the
namespace twice (once for forward declarations and then for the class
declaration), right?


Right.
You could prefix it with '::' (meaning in the global namespace).


How do I do that? I tried:
=== begin code ===
namespace VART
{
class Transform;
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
=== end code ===
But g++ gives me:
error: 'std::ostream& operator<<(std::ostream&, const
VART::BoundingBox&)' should have been declared inside '::'


So, the compiler tells you that you're referring to a function that has
not been declared. So declare it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 31 '06 #4
Victor Bazarov wrote:
If you try referring to 'Transform' inside 'VART::BoundingBox' class,
which 'Transform' would that be? Is that obvious? I am not saying
that you *can't* do that. I am saying that you *shouldn't*.


It seems pretty obvious to me :) Since method names are pointers to
code, they couldn't be where a class/type is expected. However, if you
say its not obvious to the compiler, I'll take it. The method has been
renamed. :)
You could prefix it with '::' (meaning in the global namespace).


How do I do that? I tried:
=== begin code ===
namespace VART
{
class Transform;
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
=== end code ===
But g++ gives me:
error: 'std::ostream& operator<<(std::ostream&, const
VART::BoundingBox&)' should have been declared inside '::'


So, the compiler tells you that you're referring to a function that has
not been declared. So declare it.


I don't get it. The declaration is the problem. I'll be referring to it
in the implementation. If that is not a declaration, then what is it?

May 31 '06 #5
Bruno de Oliveira Schneider wrote:
Victor Bazarov wrote:
If you try referring to 'Transform' inside 'VART::BoundingBox' class,
which 'Transform' would that be? Is that obvious? I am not saying
that you *can't* do that. I am saying that you *shouldn't*.
It seems pretty obvious to me :) Since method names are pointers to
code,


The names are names. Take a look

struct Blah { operator int() { return 42;} };
int Blah() { return 73; }

If it were allowed (or accepted), what would this be

int i = Blah();

? Is that a call to the function Blah or is that an instantiation of
a temporary of type Blah and conversion to int? What value should 'i'
get?

Names become "pointers to code" only if they are used in particular way.
If the compiler cannot distinguish between them, it will complain. Even
if the compiler *can* tell one from the other, are you sure that *you*
know which one it picks? Are you sure everybody else can tell?
they couldn't be where a class/type is expected. However, if you
say its not obvious to the compiler, I'll take it. The method has been
renamed. :)


The point here is not that the compiler can't tell, it's that *you* or
anybody else reading the code can't.
You could prefix it with '::' (meaning in the global namespace).

How do I do that? I tried:
=== begin code ===
namespace VART
{
class Transform;
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
public:
[...]
=== end code ===
But g++ gives me:
error: 'std::ostream& operator<<(std::ostream&, const
VART::BoundingBox&)' should have been declared inside '::'


So, the compiler tells you that you're referring to a function that
has not been declared. So declare it.


I don't get it. The declaration is the problem. I'll be referring to
it in the implementation. If that is not a declaration, then what is
it?


It's a "friend declaration". If you're referring to a qualified name in
a friend declaration, it must be declared prior to that. Add a "normal"
declaration of that function to the global namespace.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 31 '06 #6
Victor Bazarov wrote:
I don't get it. The declaration is the problem. I'll be referring to
it in the implementation. If that is not a declaration, then what is
it?


It's a "friend declaration". If you're referring to a qualified name in
a friend declaration, it must be declared prior to that. Add a "normal"
declaration of that function to the global namespace.


So, you are saying I need to use this huge thing below:

===boundingbox.h===
namespace VART {
class BoundingBox;
}
std::ostream& operator<<(std::ostream& output, const VART::BoundingBox&
box);

namespace VART {
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
[...]
===============

Is this the right thing to do?

May 31 '06 #7
Bruno de Oliveira Schneider wrote:
Victor Bazarov wrote:
I don't get it. The declaration is the problem. I'll be referring to
it in the implementation. If that is not a declaration, then what is
it?


It's a "friend declaration". If you're referring to a qualified
name in a friend declaration, it must be declared prior to that.
Add a "normal" declaration of that function to the global namespace.


So, you are saying I need to use this huge thing below:

===boundingbox.h===
namespace VART {
class BoundingBox;
}
std::ostream& operator<<(std::ostream& output, const
VART::BoundingBox& box);

namespace VART {
class BoundingBox {
friend std::ostream& ::operator<<(std::ostream& output, const
BoundingBox& box);
[...]
===============

Is this the right thing to do?


AFAIK, unless you want to define this operator right there, inside the
class definition (which you could), then yes, it's the only thing to do.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 31 '06 #8
Victor Bazarov wrote:
AFAIK, unless you want to define this operator right there, inside the
class definition (which you could), then yes, it's the only thing to do.


And if I want the operator to be friend of class BoundingBox, where
else could I define it?

Jun 1 '06 #9
Bruno de Oliveira Schneider wrote:
Victor Bazarov wrote:
AFAIK, unless you want to define this operator right there, inside
the class definition (which you could), then yes, it's the only
thing to do.


And if I want the operator to be friend of class BoundingBox, where
else could I define it?


You can define it anywhere you want. The rule is simple: if you don't
have it declared (or defined, since a definition is a declaration)
before the compiler sees your 'friend' declaration, the compiler
*assumes* the function is at the *same namespace level* as the class.
If that's not true, then the function has to be declared before you can
declare it a friend. IOW, you can define it anywhere you want, but you
must declare it before the compiler encounters the friend declaration.
And if you always follow that rule (instead of relying on the compiler
guessing correctly where your function will be), you will never have
any problem. Be explicit, it will make your life simpler.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 1 '06 #10
Victor Bazarov wrote:
You can define it anywhere you want. The rule is simple: if you don't
have it declared (or defined, since a definition is a declaration)
before the compiler sees your 'friend' declaration, the compiler
*assumes* the function is at the *same namespace level* as the class.
If that's not true, then the function has to be declared before you can
declare it a friend. IOW, you can define it anywhere you want, but you
must declare it before the compiler encounters the friend declaration.
And if you always follow that rule (instead of relying on the compiler
guessing correctly where your function will be), you will never have
any problem. Be explicit, it will make your life simpler.


So, I may declare it anywhere I want. But since the operator is a
friend of class BoundingBox and the friend declaration has to be inside
the class declaration, and the operator is not in same namespace as the
class, then it must be declared before the class declaration. Since I
must declare the operator before the class declaration, then I must
forward-declare the class, opening its namespace again.

So, it may be anywhere, but it has to be there. Am I missing something?
:)

Sorry about the irony. I really appreciate your help, but it seems to
me you are trying to make to broad explanations and missing the
point... that is a bit confusing...

Jun 1 '06 #11
Bruno de Oliveira Schneider wrote:
Victor Bazarov wrote:
[...explanation...]
So, I may declare it anywhere I want. But since the operator is a
friend of class BoundingBox and the friend declaration has to be
inside the class declaration, and the operator is not in same
namespace as the class, then it must be declared before the class
declaration. Since I must declare the operator before the class
declaration, then I must forward-declare the class, opening its
namespace again.


Yes, sounds right.
So, it may be anywhere, but it has to be there. Am I missing
something? :)
I guess you are. I am not going to find it for you, though. You have
to do it yourself. What is the "it" you're referring to? The operator
can be declared anywhere. To be declared a friend, the operator has
to be declared. Where? Anywhere you want. Just declare it. Now, if,
to declare the operator, you need to declare the class first, then declare
the damn class. Where? *Before the operator*.
Sorry about the irony.
It's not irony. It's an attempt at sarcasm.
I really appreciate your help, but it seems to
me you are trying to make to broad explanations and missing the
point... that is a bit confusing...


*I* am missing the point? Which point am I missing? That you don't
want to do what is required by the language? No, I'm definitely not
missing *that* point.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 1 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by MoonStorm | last post: by
2 posts views Thread by trying_to_learn | last post: by
5 posts views Thread by Alexander Gnauck | last post: by
5 posts views Thread by Christoffer | last post: by
1 post views Thread by Leonel Galan | last post: by
1 post views Thread by ax | last post: by
10 posts views Thread by Francois Malgreve | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.