I'm working in Visual Studio 2008 on a C++ programming assignment. We were supplied with files that define the following namespace hierarchy (the names are just for the sake of this post, I know "namespace XYZ-NAMESPACE" is redundant):
(MAIN-NAMESPACE){
a bunch of functions/classes I need to implement...
(EXCEPTIONS-NAMESPACE){
a bunch of exceptions
}
(POINTER-COLLECTIONS-NAMESPACE){
Set and LinkedList classes, plus iterators
}
}
The MAIN-NAMESPACE contents are split between a bunch of files, and for some reason which I don't understand the operator<< for both Set and LinkedList is entirely outside of the MAIN-NAMESPACE (but within Set and LinkedList's header file).
Here's the Set version:
template<typename T>
std::ostream& operator<<(std::ostream& os,
const MAIN-NAMESPACE::POINTER-COLLECTIONS-NAMESPACE::Set<T>& set)
Now here's the problem: I have the following data structure:
Set A
Set B
Set C
double num
It's defined to be in a class within MAIN-NAMESPACE. When I create an instance of the class, and try to print one of the sets, it tells me that:
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const MAIN-NAMESPACE::POINTER-COLLECTIONS-NAMESPACE::Set' (or there is no acceptable conversion)
However, if I just write a main() function, and create Set A, fill it up, and use the operator- it works.
Any idea what is the problem? (note: I tried any combination of using and include I could think of).
Strange - even though putting free functions associated with a type to a different namespace is a bad practice, the global namespace declarations are always visible.
The only thing I can think of is that declaration with the same name in MAIN-NAMESPACE would shadow the one in the global namespace - isn't there an operator<<, possibly for totally unrelated type, in MAIN-NAMESPACE? If so, you should fix that by using ::operator<< declaration in MAIN-NAMESPACE. Example:
namespace A
{
namespace B
{
class C{};
}
}
void f(A::B::C*);
namespace A
{
void f(int*); // try commenting
using ::f; // these two lines
void g()
{
B::C* c;
f(c);
}
}
OK I figured this out.
jpalecek's intuition about there existing another operator<< in the namespace was correct (apparently I forgot to comment it out).
The lookup rules for namespaces first start the search in the function call's namespace and search up the enclosing namespaces, right up to the global namespace (then it does the Argument dependent lookup if no match is found). However, if along the way it finds some match for operator<<, it stops the search, regardless of the fact that the types used in those functions may be incompatible, as was the case here.
The solution is either to include it into the MAIN-NAMESPACE (which I'm not allowed to), or import it from the global namespace with "using ::operator<<".
Try calling the function explicitly?
::operator<<( cout, myObj );
As SoaBox pointed out, try calling it explicitly.
For your information, if you wish to call a global function which has been hidden in the current namespace precede the function with :: to bypass the local function and call the global function.
Try calling the function explicitly?
::operator<<( cout, myObj );
Yes, that does work!
it will try to find the f function in
the current namespace (at the place of
call) or in the enclosing namespaces
of c1 and c2 types (namespace1,
namespace2::namespace3), but it will
not try other namespaces in the
search.
So let's see if I got this right: the reason invoking the operator<< from a main() function worked is because I was in the global namespace (as was operator<<).
The reason it failed when invoking from the class I implemented is because the class was in a not global namespace and there were no variables in it that pointed the compiler towards the global namespace.
OK people asked for a specific examples, so here's the relevant part of the code.
//Disclamer: in the slim case someone from my uni sees this, encounters it in the submission file, and decides I copied it or something, my student number is 311670137
This is the header file Set.h:
namespace MTM {//This is the MAIN-NAMESPACE
namespace PointerCollections {
(ITERATORS AND PREDICATE CLASSES)
template<typename T>
class Set {
public:
/////////////////////////////////
// Definitions
/////////////////////////////////
private:
/////////////////////////////////
// Definitions
/////////////////////////////////
};
///////////////////////////////////////////////////////////////////////////////
// The implementation part.
///////////////////////////////////////////////////////////////////////////////
}
}
// operator<< - the same a Set::print(std::ostream& os,
// const BinaryPredicate<T>& predicate)
// function called with the 'predicate' parameter omitted
template<typename T>
std::ostream& operator<<(std::ostream& os,
const MTM::PointerCollections::Set<T>& set){
set.print(os);
return os;
}
This is what I defined in a different file:
namespace MTM {
using std::ostream;
class Schedule {
public:
///////////////////
//Definitions, including:
///////////////////
void registerStation(string stationName);
void reportRegisteredStations(std::ostream& outputStream) const;
private: //My database
//All the classes Set recieves are defined elsewhere
Set<RegisteredStation> places;
Set<BusLine> busses;
Set<TrainLine> trains;
double tarifForBuses;
double tarifForTrains;
};
}
And here's from the main:
Schedule s();
s.registerStation("1");
s.reportRegisteredStations(cout);//This invokes the error. Definition follows:
reportRegisteredStations is defined as:
void Schedule::reportRegisteredStations(std::ostream& outputStream) const{
outputStream<<places;
}
This works for me
#include <iostream>
#include <string>
using std::string;
namespace MTM {//This is the MAIN-NAMESPACE
namespace PointerCollections {
template<typename T>
class Set {
};
}
}
template<typename T>
std::ostream& operator<<(std::ostream& os,
const MTM::PointerCollections::Set<T>& set){
return os;
}
namespace MTM {
using std::ostream;
using PointerCollections::Set;
class Schedule {
public:
///////////////////
//Definitions, including:
///////////////////
void registerStation(string stationName);
void reportRegisteredStations(std::ostream& outputStream) const;
private: //My database
//All the classes Set recieves are defined elsewhere
Set<int> places;
Set<int> busses;
Set<int> trains;
double tarifForBuses;
double tarifForTrains;
};
void Schedule::reportRegisteredStations(std::ostream& outputStream) const{
outputStream<<places;
}
}
int main()
{
MTM::Schedule s;
s.reportRegisteredStations(std::cout);
}
CORRECTION: The text below is based on experience with the g++ family of compilers. After the comment to the answer I have reread the standard (which states that ADL will be used over regular name lookup, and regular name lookup should find the operator<<). I have also tried with comeau compiler (the most standard compliant compiler I know of) and the symbol is found. It seems as a problem with g++ (tried versions 3.3, 4.1, 4.3).
Original answer:
Search for Koening lookup (technically ADL: Argument dependent lookup).
The short answer is that if you have the following class:
namespace test {
class A {};
}
the stream insertion operator should be defined as:
namespace test {
std::ostream& operator<<( std::ostream&, A const & );
}
Functions or operators should be defined in the same namespace as one of the arguments that it takes. (*)
When the compiler finds a function call such as:
namespace test2 {
void g() {
namespace1::class1 c1;
namespace2::namespace3::class2 c2;
f( c1, c2 );
}
}
it will try to find the f function in the current namespace (at the place of call) or in the enclosing namespaces of c1 and c2 types (namespace1, namespace2::namespace3), but it will not try other namespaces in the search.
(*) In this case, you are pretty much limited to the test namespace, as you are not allowed to add a function to the std namespace (only template specializations).
End of original post.
Even if as commented before this may just be a problem with the compiler, it is common usage and recommended to define all free functions that operate on a user defined type in the same namespace as the type itself.
Related
Reading and researching a lot about the new C++11 feature - "inline namespace" I don't understand what the real benefit of this feature is.
I could easily have all the functions/types which are defined in an "inline namespace" placed directly in the enclosing one and have the same result.
So what is the real motivation of placing functions/types in an inline namespace?
Grouping the functions/types?
Is there any ADL related benefit in using "inline namespace"?
I thought ADL would behave the same was as there was an implicit "using" directive for this "inline namespace."
EDIT1:
So I think the following is the key advantage.
Let's say initially we have this:
namespace toplevel {
// Users can use toplevel::MyType
inline namespace current {
class MyType {};
} // inline namespace current
} // ns toplevel
Now, some new requirements, and we need a new version
to be available but keep the old one intact:
namespace toplevel {
// Users can use toplevel::MyType
// we can let the users know that we are going to deprecate it
// in favor of toplvel::next::MyType
inline namespace current {
class MyType {};
} // inline namespace current
// Users can use toplevel::next::MyType
namespace next {
class MyType {};
} // namespace next
} // ns toplevel
And finally do this. Move inline to the "next" namespace making
it the default. Still letting the users access to "current" but
with explicit ::current - i.e. this way: toplevel::current::MyType
BTW - my preference would even rename "current" to "deprecated".
namespace toplevel {
// Users can still use it by referring
// to toplevel::current::MyType
namespace current {
class MyType {};
} // inline namespace current
// Have this one the default one
// under toplevel
// Users can use the new one this way: toplevel::MyType
inline namespace next {
class MyType {};
} // namespace next
} // ns toplevel
Does it sound like a correct scenario?
The main motivation for C++ inline namespaces does indeed involve versioning. You are on the right track with your understanding, except for the final sentence in your question:
My preference would even rename "current" to "deprecated"
The whole idea of using inline namespaces is that the namespace names aren't changing -- rather, this feature allows for the namespace names to not need to change; existing names can live on forever without requiring much change to code.
Instead, at the time a version release is made (when what we used to think of as "current features" now become "deprecated features"), the namespace names can stay the same but their default status gets updated.
Let's see this in code:
namespace MyProject {
namespace Version1 {
void BoringStableFunction() {...}
}
inline namespace Version2 {
void BoringStableFunction() {...}
void LatestAndGreatest(int x) {...}
}
}
The clients of this software probably will most often be using it by simply calling MyProject::BoringStableFunction() and maybe MyProject::LatestAndGreatest(11), perhaps without even knowing that two separate versions of MyProject exist. And that convenience can be a good thing. If a client does know that there were two different versions, and intentionally wants to use the old one (before LatestAndGreatest() had been invented), he can still do so by calling MyProject::Version1::BoringStableFunction().
Note that a client is allowed to write his code as MyProject::Version2::BoringStableFunction(). Doing so is the client essentially saying "I want to call that current #2 version, and I want that implementation which I'm using to stay the same -- even if that MyProject project gets updated later on"
Notice how I can perform additional development without affecting any of my existing clients:
namespace MyProject {
namespace Version1 {
void BoringStableFunction() {...}
}
inline namespace Version2 {
void BoringStableFunction() {...}
void LatestAndGreatest(int x) {...}
}
namespace Version3 {
void BoringStableFunction() {...}
void LatestAndGreatest(std::string x) {...}
}
}
When I'm ready to release my changes to the general public, only this tiny edit needs to be made:
namespace MyProject {
namespace Version1 {
void BoringStableFunction() {...}
}
namespace Version2 {
void BoringStableFunction() {...}
void LatestAndGreatest(int x) {...}
}
inline namespace Version3 {
void BoringStableFunction() {...}
void LatestAndGreatest(std::string x) {...}
}
}
Most of the clients had been calling MyProject::BoringStableFunction(). Their code won't need to be edited; it is still syntactically valid. But they will now suddenly be taking advantage of any new implementation that I might have changed within BoringStableFunction().
If they had been so bold as to be using my MyProject::LatestAndGreatest(11), they will need to be informed that they now need to update their usage. So this demonstrates that, even with inline namespaces, thought still needs to be put into the contract between a programmer and his client.
Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}
Could somebody tell me what is the difference between
using namespace android;
....
and
namespace android {
....
}
I found that almost all .cpp files in Android source code use the second one.
Also, If I want to include some files that use the type of second one in my own project, do I need to use namespace android{...} too?
Because if I do not, compiler would report error when I call methods of included files. Or do I need to add any prefix before method call?
namespace android {
extern int i; // declare here but define somewhere
void foo ();
}
-- is used for scoping variables and functions inside a particular name. While using/calling those variables/functions, use scope resolution operator ::. e.g.
int main ()
{
android::foo();
}
There is no restriction for putting all namespace declarations in a single body instance. Multiple namespace android bodies spread across several files, is possible and also recommended sometimes. e.g.
// x.cpp
namespace android {
void somefunc_1 ();
}
// y.cpp
namespace android {
void somefunc_2 ();
}
Now, sometimes you may find using :: operator inconvenient if used frequently, which makes the names unnecessarily longer. At that time using namespace directive can be used.
This using directive can be used in function scope / namespace scope / global scope; But not allowed in class scope: Why "using namespace X;" is not allowed inside class/struct level?).
int main ()
{
using namespace android;
foo(); // ok
}
void bar ()
{
foo(); // error! 'foo' is not visible; must access as 'android::foo()'
}
BTW, Had using namespace android; declared globally (i.e. above main()), then foo() can be accessed without :: in Bar() also.
My answer is probably only helpful if you are more experienced with Java. I'm guessing since you are doing android stuff that this is the case.
The following means that you are declaring a class called MyClass in the namespace android. The qualified name of the class would be android::MyClass.
namespace android {
class MyClass {...};
}
It can be thought of similarly to the Java code:
package android;
public class MyClass {...}
The following means that you can use classes, functions etc. defined in the android namespace without having to use their qualified name (assuming they have been included).
using namespace android;
This
#include <path/to/MyClass.h>
using namespace android;
can be thought of similarly to the Java code:
import android.MyClass;
Do I have to put code from .cpp in a namespace from corresponding .h or it's enough to just write using declaration?
//file .h
namespace a
{
/*interface*/
class my
{
};
}
//file .cpp
using a::my; // Can I just write in this file this declaration and
// after that start to write implementation, or
// should I write:
namespace a //everything in a namespace now
{
//Implementation goes here
}
Thanks.
I consider more appropriate to surround all the code that is meant to be in the namespace within a namespace a { ... } block, as that is semantically what you are doing: you are defining elements within the a namespace. But if you are only defining members then both things will work.
When the compiler finds void my::foo(), it will try to determine what my is, and it will find the using a::my, resolve my from that and understand that you are defining the a::my::foo method.
On the other hand this approach will fail if you are using free functions:
// header
namespace a {
class my { // ...
};
std::ostream & operator<<( std::ostream& o, my const & m );
}
// cpp
using a::my;
using std;
ostream & operator<<( ostream & o, my const & m ) {
//....
}
The compiler will happily translate the above code into a program, but what it is actually doing is declaring std::ostream& a::operator<<( std::ostream&, a::my const & ) in the header file --without implementation--, and defining std::ostream& ::operator<<( std::ostream &, a::my const & ) in the cpp file, which is a different function. Using Koening lookup, whenever the compiler sees cout << obj with obj of type a::my, the compiler will look in the enclosing namespaces of cout and my (std, and a) and will find that there is an a::operator<< declared but never defined in namespace a. It will compile but not link your code.
If I understood the question correctly, you can have just using a::my and then just implement the methods, like
using a::my;
void my::doSomething() {}
You can do it. But, should you?
It's an uncommon practice, and it will probably lead to a proliferation of using a::Type; for every type from namespace 'a' used in the .cc file. Whether that is a good thing is for you to decide, but I'd vote against it :)
I found this function in the header file of an abstract class:
virtual ostream & print( ostream & out ) const;
Can anyone tell me what kind of function this is and how to declare it in a derived class?
From what I can tell, it looks like it returns a reference to an outstream.
If I implement it in my cc file with nothing in it, I get a compiler error:
error: expected constructor, destructor, or type conversion before ‘&’ token
Can someone show me a simple implementation of how to use it?
You probably forgot to include iostream which makes ostream visible. You also need to change this into std::ostream, because C++ standard library names are within the namespace std.
Do not write using namespace std; in a header-file, ever!
It's ok to place it into the implementation file, if you want, or if you write up an example for a friend. Because any file that includes that header will have all of the standard library visible as global names, which is a huge mess and smells a lot. It suddenly increases the chance for name-clashes with other global names or other using'ed names - i would avoid using directives at all (see Using me by Herb Sutter). So change the code into this one
#include <iostream>
// let ScaryDream be the interface
class HereBeDragons : public ScaryDream {
...
// mentioning virtual in the derived class again is not
// strictly necessary, but is a good thing to do (documentary)
virtual std::ostream & print( std::ostream & out ) const;
...
};
And in the implementation file (".cpp")
#include "HereBeDragons.h"
// if you want, you could add "using namespace std;" here
std::ostream & HereBeDragons::print( std::ostream & out ) const {
return out << "flying animals" << std::endl;
}
some implementation:
ostream& ClassA::print( ostream& out) const
{
out << myMember1 << myMember2;
return out;
}
Returning the same ostream allows combinations like
a.print( myStream) << someOtherVariables;
However, it is still strange to use it this way.
Regarding the error, ostream is part of std namespace, and not part of the global namespace or the namespace the class you're refering is part of.
#include <iostream>
using namespace std;
struct A {
virtual ostream & print( ostream & out ) const {
return out << "A";
}
};
It is common to make a print function virtual, because the << operator commonly used for stream output cannot be made so (because it is not a member function).