How to refer to user defined literal operator inside a namespace? - c++

Consider the following:
#include <iostream>
namespace X
{
void operator ""_test(unsigned long long x)
{
std::cout << x;
}
}
int main()
{
using namespace X;
10_test;
// 10_X::test; /* doesn't work */
}
I can refer to the user defined literal operator inside the namespace X by an explicit using namespace X;. Is there any way of referring to the literal operator without explicitly including the namespace? I tried the
10_X::test;
but of course doesn't work as the parser believes X refers to the name of the operator.
X::operator ""_test(10)
works but it's clumsy.

#include <iostream>
namespace X {
inline namespace literals {
void operator ""_test(unsigned long long x) {
std::cout << x;
}
}
}
int main() {
{
using namespace X::literals;
10_test;
}
{
using X::operator""_test;
10_test;
}
}
_test is both in X and X::literals. This permits people to using namespace X::literals; without pulling in everything from X, yet within X _test is also available.
Importing an individual literal is a bit annoying.
std does this with both std::chrono and std::literals and std::chrono::literals. inline namespaces let you define subsections of your namespace that you think people would want to import as a block without getting the rest of it.

Related

How to use nested namespace to avoid ambiguity?

I have the following operators defined in the corresponding namespaces:
namespace literals
{
constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
// ...
// return a constructed id
}
namespace multiplied
{
constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
// ...
// return an id constructed in a specific way
}
} // namespace multiplied
} // namespace literals
In a .cpp file I would like to use both functions, hence I've declared using namespace literals and when I am declaring using namespace multiplied in a concrete function I am getting ambiguous call to overloaded function compile error. How can I differentiate these functions?
Test.cpp
using namespace literals;
void f()
{
// here I am using literals' _ID which is fine
const Type id{1_ID};
}
void g()
{
// here I want to use multiplied's _ID, but obviously I am failing to do so
using namespace multiplied;
const Type id{1_ID};
}
The name lookup rules for using namespace are such that the declarations introduced by it appear to be located in the inner-most namespace scope enclosing both the current namespace scope and the target namespace scope.
Therefore it is no good to disambiguate based on the scoping of multiple reachable using namespace statements.
Instead you can import the declaration with a using declaration:
void g()
{
using multiplied::operator""_ID;
const Type id{1_ID};
}
This will behave as if the operator was declared in the scope, so that name lookup will stop there and won't look at the declaration imported by the outer using namespace.
Alternatively, you can call the user-defined literal operator directly with a qualified call:
void g()
{
const Type id{multiplied::operator""_ID(1)};
}
As another possibility you can always limit the scope of the using namespace statements, so that only one of using namespace literals; or using namespace literals::multiplied; is reachable from any given scope using the operator, e.g.:
// no using namespace at this scope
void f()
{
using namespace literals;
const Type id{1_ID};
}
void g()
{
using namespace literals::multiplied;
const Type id{1_ID};
}
Consider the following code:
#include <iostream>
namespace one
{
int func(int num1, int num2)
{
return num1 * num2;
}
namespace two
{
int func(int num1, int num2)
{
return num1 * num2;
}
}
}
int f()
{
return one::two(1, 2) + 10;
}
int g()
{
return one::two::func(3, 4) + 10;
}
int main()
{
std::cout << f() << std::endl;
std::cout << g() << std::endl;
}
The above code will compile and run perfectly fine, and will work as expected, with f() using one::func() and g() using one::two::func(). If you have to write `using namespace one;' then you can do something like this:
using namespace one;
int f()
{
return func(1, 2) + 10;
}
int g()
{
return two::func(3, 4) + 10;
}
This will also result in the same output.

Rationale behind using namespace behavior

Quote from the standard:
A using-directive specifies that the names in the nominated namespace
can be used in the scope in which the using-directive appears after
the using-directive. During unqualified name lookup (3.4.1), the names
appear as if they were declared in the nearest enclosing namespace
which contains both the using-directive and the nominated namespace.
Look at this code:
namespace A {
int fn() { return 1; }
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
Here, before I knew the exact rules of namespaces, I had expected that z will be initialized to 1, as I written using namespace A, so expected that A::fn() will be used. But it is not the case, z will be initialized to 2, as Inner::fn() is called because of the rule I quoted.
What is the rationale behind this behavior: "as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace"?
What would be the cons, if using namespace worked as applying using declarations for everything in that namespace?
Note: this is the related issue that motivated me to ask this question.
A desirable property of a namespace system is that of what I call incremental API compatibility. That is, if I add a symbol to a namespace, then any previously working program should keep working and mean the same thing.
Now, plain C++ with overloads is not incrementally API compatible:
int foo(long x) { return 1; }
int main()
{
foo(0);
}
Now I add the overload int foo(int x) { return 2; } and the program silently changes meaning.
Anyway, when C++ people designed the namespace system they wanted that when incrementing an external API, previously working code should not change the namespace from where the symbol is chosen. From your example, the previous working code would be something like:
namespace A {
//no fn here, yet
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
And z is easily initialized to 2. Now augmenting namespace A with a symbol named fn will not change the meaning of that working code.
The opposite case does not really apply:
namespace A {
int fn() { return 1; }
}
namespace Inner {
// no fn here
namespace B {
using namespace A;
int z = fn();
}
}
Here z is initialized to 1. Of course, if I add fn to Inner it will change the meaning of the program, but Inner is not an external API: actually, when Inner was written initially, A::fn did already exist (it was being called!), so there is no excuse for being unaware of the clash.
A somewhat practical example
Imagine this C++98 program:
#include <iostream>
namespace A {
int move = 0;
void foo()
{
using namespace std;
cout << move << endl;
return 0;
}
}
int main()
{
A::foo();
return 0;
}
Now, if I compile this with C++11, everything works fine thanks to this using rule. If using namespace std worked as applying using declarations for everything in that namespace, then this program would try to print function std::move instead of A::move.

using namespace does not work for definitions?

I am having trouble understanding c++ namespaces. Consider the following example:
//distr.h
namespace bogus{
extern const int x;
extern const int y;
double made_up_distr(unsigned param);
}
Now if I define my variables like the cpp below everything compiles fine
//distr.cpp
#include "distr.h"
#include <cmath>
const int bogus::x = 10;
const int bogus::y = 100;
double bogus::made_up_distr(unsigned param){
auto pdf = (exp(param) / bogus::x) + bogus::y;
return pdf;
}
But if I try to simply bring in the bogus namespace and use instead
//broken distr.cpp
#include "distr.h"
#include <cmath>
using namespace bogus;
const int x = 10;
const int y = 100;
double made_up_distr(unsigned param){
auto pdf = (exp(param) / x) + y;
return pdf;
}
My compiler tells me that the reference to x and y is ambiguous.
Why is that?
There's a simple reason why this can't plausibly work the way you expected:
namespace bogus {
const int x;
}
namespace heinous {
const int x;
}
using namespace bogus;
using namespace heinous;
const int x = 10;
now, should x above refer to bogus::x, heinous::x or a new global ::x?
It would be the third without the using statements, which means here that adding a using statement would change the meaning of existing code in a particularly subtle way.
The using statement is used to introduce the contents of a scope (usually but not necessarily a namespace) for lookup. The statement
const int x = 10;
wouldn't normally require a lookup in the first place, except to detect an ODR violation.
Name lookup for the identifier in declarations/definitions doesn't work the same way as name lookup in usage. In particular, it doesn't care about using statements. There is a very simple reason for this: if it were different, it would lead to all sorts of nasty surprises. Consider this:
// sneakattack.h
namespace sneakattack { void foo(); }
using namespace sneakattack;
// somefile.cpp
#include "sneakattack.h"
void foo() { std::cout << "Hello\n"; }
// otherfile.cpp
void foo();
int main() { foo(); }
This program currently works: the declaration sneakattack::foo is ignored, and the definition ::foo is correctly linked to the use in otherfile. But if name lookup worked differently, somefile would suddenly define sneakattack::foo, not ::foo, and the program would fail to link.

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.

In C++, what is a "namespace alias"?

What is a "namespace alias" in C++? How is it used?
A namespace alias is a convenient way of referring to a long namespace name by a different, shorter name.
As an example, say you wanted to use the numeric vectors from Boost's uBLAS without a using namespace directive. Stating the full namespace every time is cumbersome:
boost::numeric::ublas::vector<double> v;
Instead, you can define an alias for boost::numeric::ublas -- say we want to abbreviate this to just ublas:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Quite simply, the #define won't work.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Compiles fine. Lets you work around namespace/class name collisions.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
On the last line, "Hmm:Oops" is a compile error. The pre-processor changes it to Nope::Oops, but Nope is already a class name.
More on this topic http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
It is all about choosing an alias for a looong namespace name, such as:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Then later, you can typedef
typedef SHORT::mytype
instead of
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
This syntax only works for namespaces, cannot include classes, types after the namespace NAME =
Also note that namespace aliases and using directives are resolved at compile time, not run time. (More specifically, they're both tools used to tell the compiler where else to look when resolving names, if it can't find a particular symbol in the current scope or any of its parent scopes.) For example, neither of these will compile:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Now, a curious mind may have noticed that constexpr variables are also used at compile time, and wonder whether they can be used in conjunction with either an alias or a directive. To my knowledge, they cannot, although I may be wrong about this. If you need to work with identically-named variables in different namespaces, and choose between them dynamically, you would have to use references or pointers.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
The usefulness of the above may be limited, but it should serve the purpose.
(My apologies for any typoes I may have missed in the above.)
Namespace is used to prevent name conflicts.
For example:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
You now have two classes name bar, that are completely different and separate thanks to the namespacing.
The "using namespace" you show is so that you don't have to specify the namespace to use classes within that namespace. ie std::string becomes string.
my resource: https://www.quora.com/What-is-namespace-in-C++-1