void fun(){
std::cout << "hello" << std::endl;
}
namespace enc{
using ::fun;
}
This code above gives no error. I want to understand what's going on here.
What does using ::fun; mean?
Breaking this down we have:
void fun() is a function that does not return a value (essentially nothing).
:: is a scope resolution operator. For example, cout and cin are defined in the std namespace. To qualify their names without using the using declaration we have to qualify them with std::cout and std::cin
To answer the main question, however:
using ::fun; is called a using declaration. A using declaration means that you can introduces namespace members into other namespaces, etc. This means that fun will now be visible as ::enc::fun;
For example:
void fun() {
std::cout << "hello" << std::endl;
}
namespace enc {
using ::fun;
}
void Reallyfun()
{
enc::fun(); // Which calls ::fun
}
using a synonymous declaration introduces a name from one declarative region into another. In this case, the name fun is introduced into the namespace ::enc and it is synonymous with ::fun.
Related
In book "C++ Primer" fifth edition, there is a line "Entities with the same name defined in an outer scope are hidden" in the second page of Section 18.2.2. This sentence is underlined with red as follows:
I tried to repeat the claim in an experiment. The experimental code is as follows:
#include <cstdlib>
#include <iostream>
#include <cmath>
int abs(int n) {
std::cout << "here" << std::endl;
return 0;
}
void test() {
using std::abs;
std::cout << abs(7) << std::endl;
}
int main(int argc, char** argv) {
test();
return 0;
}
using std::abs is a using declaration, so, if the claim in "C++ Primer" is correct, the user-defined abs() function should be hidden by std::abs(). But the result is that it is the user-defined abs() function that is called. So, if the book is correct, there must be something wrong in my experiment. How do I write the experimental code to confirm the sentence in "C++ Primer"? If the book is incorrect, what should the correct exposition be that can replace the sentence? Thank you.
PS: I tried in both Windows10+VS2015 and Ubuntu 18.04+g++7.4. Both called user-defined abs() and printed out "here".
The book could do a better job of explaining it, but it isn't wrong. It's just that the lookup rules for overloads are somewhat more nuanced, because overloads of the same name may coexist in the same scope normally, so a using declaration mingles well with that.
If you were to indeed define a new entity that is not an overload, for instance
void test() {
int abs = 0;
std::cout << abs(7) << std::endl;
}
Then that call expression would be ill-formed, because the outer callable entities are hidden by the inner int variable. The way to work around it would be with a using declaration
void test() {
int abs = 0;
{
using std::abs; // Let the name refer to the functions again
using ::abs; // the variable abs is hidden
std::cout << abs(7) << std::endl;
}
}
This experiment should illustrate what the book meant.
This is solely for example I happen to notice with!
I'm using cout with operator<< and why won't this program compile?
Why aren't they being considered the way function overloadings are?
#include <iostream> // imports the declaration of std::cout
using namespace std; // makes std::cout accessible as "cout"
int cout() // declares our own "cout" function
{
return 5;
}
int main()
{
cout << "Hello, world!"; // Compile error!
return 0;
}
At the point of the attempted stream insertion, there are two names cout in global scope: one from the standard library, std::cout, pulled into global scope by that infernal using declaration, and one defined as a function int cout(). In the expression
cout << "Hello, world!\n";
the use of cout is ambiguous. There is no function overloading for two reasons: first, std::cout is not a function, so would not take part in overloading. But more fundamentally, the use of cout in that expression is not a function call, so, again, there is no overloading. The name cout from the function definition is treated as a pointer to function, and the name cout from namespace std is the name of an object. There are two possible interpretations of that name, so its use in that << expression is ambiguous.
Is there a possibility to limit the scope of literal operators?
I would like to define some postfixes to make some things easier to specify, but this only has relevance to things directly connected to the specific class or the their child classes. Name spaces of other code that uses this classes should not be affected by this.
Use a namespace. wandbox example
namespace my_lits
{
int operator ""_aaa(const unsigned long long x)
{
return x + 1;
}
}
int main()
{
{
using namespace my_lits;
std::cout << 100_aaa << "\n";
}
{
// Will not compile!!!
std::cout << 100_aaa << "\n";
}
}
Is there a way to make this namespace always visible then in class' scope?
It is not possible to bring a namespace into scope inside a class. Refer to this question and this other one for more details.
Furthermore, UDLs cannot be declared in class scope.
I have two namespaces that each have a function with the same name. If from one of the namespaces I want to call the function that matches the best. From a function in NamespaceA, if I call MyFunction(...), of course it uses the one in NamespaceA. However, if I add a 'using NamespaceB::MyFunction', I would then expect the behavior I described. However, what I actually see is that it ALWAYS finds the NamespaceB function, even though I am in NamespaceA. HOWEVER, if I ALSO add a using::NamespaceA (even though I am already in NamespaceA), it works as I'd expect. A demonstration is below. Can anyone explain how this works?
#include <iostream>
namespace NamespaceA
{
void DoSomething();
void MyFunction(int object);
}
namespace NamespaceB
{
void MyFunction(float object);
}
namespace NamespaceA
{
void DoSomething()
{
using NamespaceA::MyFunction; // Note that without this line the lookup always fins the NamespaceB::MyFunction!
using NamespaceB::MyFunction;
MyFunction(1);
MyFunction(2.0f);
}
void MyFunction(int object)
{
std::cout << "int: " << object << std::endl;
}
}
namespace NamespaceB
{
void MyFunction(float object)
{
std::cout << "float: " << object << std::endl;
}
}
int main(int argc, char *argv[])
{
NamespaceA::DoSomething();
return 0;
}
It has to do with the order in which different parts of the program are looked in to find a name. For the situation you mention, it has to do with the scope of the function's top-level block being searched for before the enclosing namespace. Basically, the using declaration brings that name into the top-level scope of DoSomething, and since that scope is looked in before the enclosing namespace scope, then if a matching function is found there, then the enclosing namespace scope isn't considered.
I have glossed over a lot of stuff that isn't relevant in your example (for example, if the argument were not a built-in type then, believe it or not, names from the scope where that type was defined could be considered as well. For the whole story, see section 3.4 here. It's pretty scary, about 13 pages to describe all this stuff; but don't bother with it unless you really are curious, because most of the stuff is there so that it "works the way you expect", more-or-less. That document is not the real Standard but actually a working draft with some corrections, so it is basically the real C++ Standard plus some bugfixes.
i believe namespaces use the same scoping rules as variables. so if you have a local namespace, lookups will happen there first before moving to the outer scope.
i'm not sure what the rules are for the situation where you have imported two namespaces with the same function names, but you should always fully qualify the function calls in that scenario just for clarity, instead of relying on some nuance of the language implementation for namespaces that people may not be familiar with.
Short answer: Local defined name and the name declared by a using-declaration hides nonlocal names.
Detailed answer:
Your question is very interesting. I didn't open standarts of C++98,03,11 for that question, but open Bjarne Stroustrup's book
Namespace - is a named scope. Verbosity can be eliminated using two techniques:
create synonymous with using NS :: x; (using-declaration)
create synonymous for all the variables with using namespace NS :: x; (using-directive)
The answer to your question is here:
Appendix B 10.1
local definitions, and names defined with using-declaration hides
the name of a non-local definitions.
Bonus with opposite situation:
Also if you
using NamespaceA::MyFunction;
using NamespaceB::MyFunction;
change to
using namespace NamespaceB;
Then you due to text below get situation with call only void MyFunction(int object)
8.2.8.2
Names explicitly declared in namespace (also made with using declaration)
have priority over the names made available by using directives
Extra code to play with:
#include <iostream>
// var in global namespace
const char* one = "G_one";
// vars in named namespace
namespace NS1 {
const char* one = "NS1_one";
const char* two = "NS1_two";
const char* three = "NS1_three";
}
namespace NS2 {
const char* one = "NS2_one";
const char* two = "NS2_two";
const char* three = "NS2_three";
}
int main(int argc, char *argv[])
{
using namespace NS1; // using-directive
using namespace NS2; // using-directive
// const char* two = "L_two"; // local namespace
using NS2::two; // using-declaration
// C++ rules
// Local names and names with using-declarations
// takes precedence over the name of the NS
std::cout << "two: " << two << std::endl;
//std::cout << "three: " << three << std::endl; // ambiguous symbol
// But the name in global-namespace does not have priority over imported name from namespace
//std::cout << "one: " << one << std::endl; // ambiguous symbol. Because wGlobal names does not have priority over
return 0;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the meaning of prepended double colon “::” to class name?
I have been looking at a legacy C++ code and it had something like this:
::putenv(local_tz_char);
::tzset();
What does this syntax of prepending "::" to the function calls mean? Google-fu is failing me.
It means that the functions putenv() and tzset() will be looked up by the compiler in the global namespace.
Example
#include <iostream>
using namespace std;
//global function
void foo()
{
cout << "This function will be called by bar()";
}
namespace lorem
{
void foo()
{
cout << "This function will not be called by bar()";
}
void bar()
{
::foo();
}
}
int main()
{
lorem::bar(); //will print "This function will be called by bar()"
return 0;
}
Also known as Scope resolution operator
In C++ is used to define the already declared member functions (in the
header file with the .hpp or the .h extension) of a particular class.
In the .cpp file one can define the usual global functions or the
member functions of the class. To differentiate between the normal
functions and the member functions of the class, one needs to use the
scope resolution operator (::) in between the class name and the
member function name i.e. ship::foo() where ship is a class and foo()
is a member function of the class ship.
Example from Wikipedia:
#include <iostream>
// Without this using statement cout below would need to be std::cout
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
There was a discussion yesterday (+ a year) on a similar question. Perhaps you can find a more indepth answer here.
What is the meaning of prepended double colon "::"?
It means: look up the function in the global namespace.
It will use the specifically unqualified name (as opposed to anything imported with the using keyword).
the :: is the scope resolution operator, it tells the compiler in what scope to find the function.
For instance if you have a function with a local variable var and you have a global variable of the same name, you can choose to access the global one by prepending the scope resolution operator:
int var = 0;
void test() {
int var = 5;
cout << "Local: " << var << endl;
cout << "Global: " << ::var << endl;
}
The IBM C++ compiler documentation puts it like this (source):
The :: (scope resolution) operator is used to qualify hidden names so
that you can still use them. You can use the unary scope operator if a
namespace scope or global scope name is hidden by an explicit
declaration of the same name in a block or class.
The same can be done for methods inside a class and versions of the same name outside. If you wanted to access a variable, function or class in a specific namespace you could access it like this: <namespace>::<variable|function|class>
One thing to note though, even though it is an operator it is not one of the operators that can be overloaded.