1. namespace is just like how Scheme represent functional environments using the let syntax, execept namespace allows you to give a name to the environment for other files to references to it (let itself in Scheme doesn't do it, you must use define syntax to define a variable and then combine it with the let)
2. to reference to a namespace env, you can using either syntax: using namespace name; or directive syntax :: . those 2 things mean totally different things, however:
using namespace name;
using syntax basically loads all the env variable symbol into the current env, but does not bind them automatically! those symbols will be bind to the definition during linking. it is less powerful than the directive :: . it probably work like this:
load into current env symbol binding pair (symbol,
directive ::
the directive is more powerful, it automatically binds the env symbol to the definition. using directive does not create any symbol binding in the env, but just directly links the namespace_symbol::symbol into the definition directly inside the namespace
alternatively, you are also allowed to write:
using namespace name::symbol;
this declaration work just like directive, binding the env symbol to the definition right away, also making the rest of the env to alias any symbol without the namespace declaration to the same symbol defined inside the namespace. i.e.
using namespace std::string;
string st = "string";
this code basically says load namespace
-----------------------------------------------------
so, with the compiler behaivior defined, here comes the interesting part: classes and data in a namespace are compiled as part of the namespace, i.e. if thinking of namespace as functions with its own scope, then the local variables are basically being part of the function, whereas functions being declared inside this function is not physically inside this function, but through compilation, is in another part of the program that is labeled to be inside this function's local env.
now this leads to a problem, whenever you declare a function inside a namespace, and you declare it in one .cpp file, inside the file you used the
directive symbol loading to define the function, the function is not automatically linked into the header file's namespace function because the using directive only loads the name, but since .cpp files can also have functions for itself, it assumes this function belong to the file, not the namespace during linking.
so as a result, an linking error pops whenever you use this function somewhere else, saying this function is not defined.
however, this will not happen to namespace objects and data using the
------------------------------------------------------------
on side note, namespace can be declared without a name, creating an anonymous environment, but it behaves like this:
namespace uniquely_generated_label{
data...
}
using namespace uniquely_generated_label;
which actually looks quite like the Dr.Scheme functional define + let thingie.
though, those unamed namespace can only be used inside the file that declares it.
TODO: try what happens to the env symbol if 1 symbol is inside of 1 un-named namespace of another un-named namespace, and being accessed outside both namespaces at the later part of the file
UPDATE 1:
typing
using namespace nspace::func1;
will generate an error stating that func1 is not an object in namespace, this could only mean that c++ treats functions just as primitive as C, where all functions are basically from the same environment, any functions that are inside a namespace basically have the compiler extended their function name with the namespace name. and therefore, functions are not treated as objects still, just a name tag.
this leaves only 1 way to define any functions in C++ namespace: using the :: directive.
more on namespace without names later
No comments:
Post a Comment