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? 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
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 '::'
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
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?
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
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?
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
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?
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
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...
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 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 Adam Child |
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 Andy Fish |
last post: by
|
10 posts
views
Thread by Francois Malgreve |
last post: by
| | | | | | | | | | |