Unnamed namespace and default function arguments - c++

I was wondering, how I could set a const member variable of an unnamed namespace as a default function parameter where the function is declared in an named namespace.
Well I guess this is hard to explain for me, here is an example of what I want to do:
//foo.h
namespace foo
{
void justAFunction(std::string function_string = unnamed_str);
}
//foo.cpp
#include "foo.h"
namespace foo
{
namespace
{
const std::string unnamed_str = "simple string";
}
void justAFunction(std::string function_string)
{
...
}
}
This does not link...
I could still write the default parameter in the function definition, but that is not what I want, since the caller won't see it, right?
Any advice how to code this correct?

Related

Is a fully qualified class name down to global scope ever required for out-of-line member function definitions?

This question got me wondering whether it is ever useful/necessary to fully qualify class names (including the global scope operator) in an out-of-class member function definition.
On the one hand, I've never seen this done before (and the syntax to properly do so seems obscure). On the other, C++ name lookup is very non-trivial, so maybe a corner case exists.
Question:
Is there ever a case where introducing an out-of-class member function definition by
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
would differ from
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... } (no global scope :: prefix)?
Note that member function definitions must be put into a namespace enclosing the class, so this is not a valid example.
A using-directive can cause Fully to be ambiguous without qualification.
namespace Foo {
struct X {
};
}
using namespace Foo;
struct X {
void c();
};
void X::c() { } // ambiguous
void ::X::c() { } // OK
It's necessary if one is a masochist and enjoys writing stuff like this
namespace foo {
namespace foo {
struct bar {
void baz();
};
}
struct bar {
void baz();
};
void foo::bar::baz() {
}
void (::foo::bar::baz)() {
}
}
One can of course write the second overload as foo::foo::bar::baz in global scope, but the question was whether or not the two declarations can have a different meaning. I wouldn't recommend writing such code.
If a using directive is used then there can be a confusing code.
Consider the following demonstrative program
#include <iostream>
#include <string>
namespace N1
{
struct A
{
void f() const;
};
}
using namespace N1;
void A::f() const { std::cout << "N1::f()\n"; }
struct A
{
void f() const;
};
void ::A::f() const { std::cout << "::f()\n"; }
int main()
{
N1::A().f();
::A().f();
return 0;
}
So for readability this qualified name
void ::A::f() const { std::cout << "::f()\n"; }
shows precisely where the function is declared.

Namespace set as Used because of One Type Inside being Used?

I just noticed this. I don't know why this is the case, if i use one element from a namespace i don't want anything else to be accessible without having to use the namespace. For example here, this code is valid:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
};
using Magic = Test::Magic;
int main()
{
Alakazam(Magic()); // valid
Alakazam(Test::Magic2()); // valid
Test::Alakazam(Magic()); // what i want to only be valid
Test::Alakazam(Test::Magic2()); // this too
}
Any reasoning behind this? Does the spec state that this has to be true?
As suggested by immbis in the comment, this is defined by the standard:
3.4.2: Argument dependent name lookup
When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual
unqualified lookup may be searched, and in those namespaces,
namespace-scope friend function or function template declarations not
otherwise visible may be found. These modifications to the search
depend on the types of the arguments (and for template template
arguments, the namespace of the template argument).
...
If you want to defeat this mecanism, you have to use nested namespace like this, but it's tricky:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
namespace Test2 { // use a nested namespace that will not be searched autoamtically
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
}
using namespace Test2; // but give some access to the enclosing namespace
};
Live Demo : Then, your two first calls will not be valid any longer. However, the last call in your example is still possible: you can't prevent the use of fully qualified names outside of the namespace.

Why do i need NOT use the namespace?

So i have the following functions:
GraSys::CRectangle GraSys::CPlane::boundingBox(std::string type, std::string color)
{
CRectangle myObject = CRectangle(color);
return myObject;
}
Since boundingBox is part of the namespace GraSys and i have to use it in order to declare this function , why i don't need to do this inside the function?, why can i just use? why does it let me compile with out a problem ?
CRectangle myObject = CRectangle(color);
insted of :
GraSys::CRectangle myObject = GraSys::CRectangle(color);
Hope my question is not confusing.
You're implementing a function that is declared in the namespace of GrasSys. When you're in that function, you use the declaring name space.
For clarity, consider:
namespace GraSys {
class CRectangle { ... };
class CPlane {
... boundingBox(...); ...
}
void example(...) { ... };
}
When you implement boundingBox, you will be in the namespace declared during the declaration of the function, which is GraSys. CRectangle is declared within GraSys, so you can use it directly. Similarly, note that you can directly call functions as well, so in the above code, you can directly call example in your boundingBox implementation.
This is called unqualified name lookup. You can read the complete lookup rules in the C++ standard section 3.4.1 or in more human-readable form here.
Here is an example from the standard, which may be better than verbose explanations:
namespace A {
namespace N {
void f();
}
}
void A::N::f() {
i = 5;
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of A::N::f, before the use of i
// 2) scope of namespace N
// 3) scope of namespace A
// 4) global scope, before the definition of A::N::f
}
using namespace is like add the name space to the global name space (i.e the :: name space). if you do it, from now on the compiler will look for each symbol in all the used name spaces.
Only in case there is ambiguity (mean a symbol with the same name declared in 2 used name spaces, you will be have to use the namespace for it.
namespace A{
void f();
void g();
}
namespace B{
void g();
}
using namespace A;
using namespace B;
A::f(); //always work
f(); //work since it is the only symbol named f
A::g();//always work
B::g();//always work
g();// error since g is ambiguous.

static struct in anonymous namespace

that this snippet of code actually do?
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
void test();
namespace {
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
}
int main(void) {
return 0;
}
void test() {
printf("testing function\n");
}
why does the test function actually get called? and why use the "anonymous" namespace? I found this piece of code in an open source project...
This:
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
Is equivalent to this:
struct StaticStruct {
StaticStruct() {
test();
}
};
static StaticStruct TheStaticSupport;
It defines a type named StaticStruct and an instance of the type named TheStaticSupport with internal linkage (though, since it is declared in an unnamed namespace, the static is redundant).
The constructor for TheStaticSupport is called before main() is entered, to construct the object. This calls the test() function.
The anonymous namespace gives the contained objects internal linkage, as their fully qualified name can never be known to anyone outside the translation unit. It's the sophisticated man's version of the old static in C.
Note that you do declare a global object of type StaticStruct, and its constructor (which runs before main() is called) calls test().

Anonymous Namespace Ambiguity

Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.