A viable function with a default argument - c++

The following example is given in N4296::13.3.3 [over.match.best]
namespace A
{
extern "C" void f(int = 5);
}
namespace B
{
extern "C" void f(int = 5);
}
using A::f;
using B::f;
void use()
{
f(3); // OK, default argument was not used for viability
f(); // Error: found default argument twice
}
I tried to write something similar:
#include <iostream>
namespace A
{
void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}
namespace B
{
void foo(int a = 5){ std::cout << a << std::endl; }
}
using A::foo;
using B::foo;
int main()
{
foo(2); //Error
}
DEMO
But I got a compile-time error. Why does the Standard says that it's OK?

The difference is the extern "C", which affects namespace membership of the function:
From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1138.pdf
What remains is the definition of “same entity” with respect to ‘extern “C”’ language linkage? This is
addressed by 7.5¶6:
“At most one function with a particular name can have C language linkage. Two
declarations for a function with C language linkage with the same function name
(ignoring the namespace names that qualify it) that appear in different namespace scopes
refer to the same function. Two declarations for an object with C language linkage with
the same name (ignoring the namespace names that qualify it) that appear in different
namespace scopes refer to the same object.”

That's because the two functions are imported from their namespace, this means that the same function has 2 definitions, you can solve it like this:
#include <iostream>
namespace A
{
void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}
namespace B
{
void foo(int a = 5){ std::cout << a << std::endl; }
}
int main()
{
A::foo(2);
B::foo(3);
}

Related

Impact of namespaces on C++ template deduction priority

while trying to implement a metafunction, which needs to exist only if the "abs" function exists for some type, i ran into the folowing problem:
Here are two examples of code i would expect to yield the same results but in fact, they do not:
First example
#include <iostream>
#include <cmath>
using namespace std;
struct Bar{};
template<typename T>
int abs(T& v)
{
return -1;
}
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
int main()
{
test();
}
Yields:
2
-1
Which is what i expect
Second example
#include <iostream>
#include <cmath>
namespace Foo
{
struct Bar{};
using namespace std;
template<typename T>
int abs(T& v)
{
return -1;
}
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
}
int main()
{
Foo::test();
}
Yields:
-1
-1
Why using a namespace here is making the compiler prioritize the "local" abs methodthe over std::abs?
In the second case the using directive places declared names in the nominated namespace in the global namespace for unqualified name lookup. So within the namespace Foo the unqualified name abs declared in this namespace is found. That is the name abs declared in the namespace Foo hides the name abs declared in the global namespace.
From the C++ 14 Standard (7.3.4 Using directive)
2 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. [ Note: In this context, “contains” means
“contains directly or indirectly”. — end note ]
The nearest enclosing namespace in the second program is the global namespace.
Below there are two more programs that demonstrate the same principle of the unqualified name lookup when a using directive is used.
#include <iostream>
void s() { std::cout << "The function s() called.\n"; }
struct s
{
s() { std::cout << "The constructor of struct s called.\n"; }
};
void test()
{
s();
}
int main()
{
test();
}
The program output is
The function s() called.
In this demonstration program the declaration of the function s hides the declaration of the structure s.
Second program.
#include <iostream>
namespace N1
{
void s() { std::cout << "The function N1::s() called.\n"; }
}
namespace N2
{
using namespace N1;
struct s
{
s() { std::cout << "The constructor of struct N2::s called.\n"; }
};
void test()
{
s();
}
}
int main()
{
N2::test();
}
The program output is
The constructor of struct N2::s called.
In this case the declaration of the structure with the name s hides the function with the same name s the declaration of which was placed in the global namespace due to the using directive.
For the reason why this takes place you can refer to Vlad's answer. However, if you want to still be able to perform the testing, you can do the testing in separate namespace.
#include <iostream>
#include <cmath>
namespace Foo
{
template<typename T>
int abs(T& v)
{
return -1;
}
}
namespace Test
{
struct Bar{};
using namespace std;
using namespace Foo;
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
}
int main()
{
Test::test();
}
The output is
2
-1

C++ Namespace Convention

I am new to C++.
I have a file that has the following:
namespace A {
namespace B {
function foo() {
}
}
function bar() {
}
}
and another file has the following:
namespace A {
namespace C {
// Call foo() and bar() here.
}
}
If I want to call foo and bar inside of namespace C, should I include their absolute namespace?
A::B::foo();
A::bar();
or I don't have to include the namespace A since they are all inside A?
B::foo();
bar();
This is a name lookup question.
So if you've read this, you'll know the difference between Unqualified Lookup and Qualified Lookup
So obviously, unqualified lookup is valid here, but if you want to do some work like disambiguation, you may use qualified lookup. So, qualified lookup is always valid when unqualified lookup is valid.(If you can use qualified lookup).
Just little addition. As Constructor said, qualified lookup always generates well-formed code, but that code does not always produce an expected result. Consider this disambiguation example
#include <iostream>
void foo();
void foo(float);
namespace Boo {
using ::foo;
void foo(int a) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
}
void foo() { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
void foo(int a) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
void foo(float) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
using namespace Boo;
int main(int argc, char *argv[])
{
foo(); // no error!
Boo::foo(); // still same
//foo(3); // aw, there are three of them. Bad, bad `using namespace`!
Boo::foo(3);
Boo::foo(3.f);
return 0;
}
namespace Boo propagates name foo to be Boo::foo. We had defined foo() after namespace declaration, but prototype declaration required to be known before.
Now imagine that Boo is std, foo prototypes are something like abs or sin from standard header and are declared that way. Header implementations are allowed to use trick from above. Result of re-definition of names used in standard namespace is described as undetermined, because depending of if using was in implementation or not, the program would use standard or user-defined function with no regard to qualified name.
TL;DR: Result of qualified lookup is always correct but is not always well-determined if reserved names are not respected.

using namespace & overloaded function

I don't understand why I get the error "ambiguous call to overloaded function".
Before "main", I declared to use namespace "second".
My expected output is:
this is the first foo
this is the second foo
this is the second foo
#include <iostream>
using namespace std;
namespace first {
void foo() {
cout << "this is the first foo" << endl;
}
}
namespace second {
void foo() {
cout << "this is the second foo" << endl;
}
}
void foo() {
cout << "this is just foo" << endl;
}
using namespace second;
void main() {
first::foo();
second::foo();
foo();
}
Before "main", I declared to use namespace "second".
When you do this, second::foo is introduced into the global namespace, then for foo(); both second::foo and ::foo are valid candidates.
You can specify that you want to call the global foo explicitly, i.e.
::foo();
Or use using-declaration inside main() instead of using-directive, e.g.
int main() {
using second::foo;
first::foo();
second::foo();
foo();
}
The reason this is happening is because of your: using namespace second;
When you do this you qualify the function foo() from the second namespace into the global scope. In the global scope, there exists another function foo() with the exact same signature. Now, your calls to first::foo() and second::foo() are fine. However, when you get to your call to foo(), the compiler doesn't know whether it should call just foo() or second::foo() since they are ambiguous, and at this point they are both in the global namespace.
Your using namespace second; is precisely the reason you get the error. It practically tells the compiler to treat second::foo as if it was in the global namespace. So now you have two foos there.
By the way, void main is not valid C++. It must be int main.
Firstly, replace void main() { } with
int main() {
return 0;
}
Secondly, using namespace second; should be inside main() from where you want to call particular namespace, not globally.
Finally, If you are using ::scope resolution operator then you don't have to mention using namespace second in the main(), use either one.
Just do like below
int main() {
first::foo(); /* first foo will be called */
second::foo(); /* second foo() will be called */
foo(); /* global foo() will be called */
return 0;
}

What is the meaning of the sentence referring to functions introduced by a using declaration?

I'm studying the C++03 Standard and am now reading [7.3.3]/11, but I'm having trouble understanding the following passage:
If a function declaration in namespace scope or block scope has the same name and the same parameter
types as a function introduced by a using-declaration, and the declarations do not declare the same function,
the program is ill-formed.
I haven't found any examples of this situation anywhere and I don't understand the meaning of this passage.
What it means is that:
namespace namespace_1
{
void foo(int number);
}
using namespace_1::foo;
void foo(int roll_no);
This means the program is ill-formed.
I believe it means to say that the function would be confusing to read. As at one point, the function definition would be using the passed int as an integer(general) but in the other case, we'd be using it as a roll_no.
This would also cause ambiguity in overloaded function matching.
The source you are citing gives an example just below the lines you have cited:
namespace B {
void f(int);
void f(double);
}
namespace C {
void f(int);
void f(double);
void f(char);
}
void h() {
using B::f; // B::f(int) and B::f(double)
using C::f; // C::f(int), C::f(double), and C::f(char)
f('h'); // calls C::f(char)
f(1); // error: ambiguous: B::f(int) or C::f(int)?
void f(int); // error: f(int) conflicts with C::f(int) and B::f(int)
}
The following program contains the error
#include <iostream>
namespace _1{
int f(){
std::cout << "_1::f\n";
}
}
namespace _2{
/*
*If a function declaration in namespace scope or block scope has the
*same name and the same parameter types as a function introduced by
* a using-declaration
*/
using _1::f;
// This is not the same function as introduced by the using directive
int f(){
std::cout << "_2::f\n";
}
}
int main(){
_2::f();
}
The diagnostic is
main.cpp: In function ‘int _2::f()’:
main.cpp:13:11: error: ‘int _2::f()’ conflicts with a previous declaration
int f(){
As a contrast, the following program is correct. The _1 namespace is introduced via a using directive.
#include <iostream>
namespace _1{
int f(){
std::cout << "_1::f\n";
}
}
namespace _2{
using namespace _1;
int f(){
std::cout << "_2::f\n";
}
}
int main(){
_2::f();
}
With the expected output
_2::f
As for the same situation in block scope you have
#include <iostream>
namespace _1{
int f(){
std::cout << "_1::f\n";
}
}
namespace _2{
int g(){
// As before but in block scope.
using _1::f;
int f();
f();
}
int f(){
std::cout << "_2::f\n";
}
}
int main(){
_2::f();
}
The diagnostic is identical
main.cpp: In function ‘int _2::g()’:
main.cpp:15:15: error: ‘int _2::f()’ conflicts with a previous declaration
int f();
^
The parallel construct of the successful sample above would be
#include <iostream>
namespace _1{
int f(){
std::cout << "_1::f\n";
}
}
namespace _2{
int g(){
using namespace _1;
int f();
f();
}
int f(){
std::cout << "_2::f\n";
}
}
int main(){
_2::g();
}
With the output
_2::f

How do I reference an external C++ namespace from within a nested one?

I have two namespaces defined in the default/"root" namespace, nsA and nsB. nsA has a sub-namespace, nsA::subA. When I try referencing a function that belongs to nsB, from inside of nsA::subA, I get an error:
undefined reference to `nsA::subA::nsB::theFunctionInNsB(...)'
Any ideas?
Use global scope resolution:
::nsB::TheFunctionInNsB()
#include <stdio.h>
namespace nsB {
void foo() {
printf( "nsB::foo()\n");
}
}
namespace nsA {
void foo() {
printf( "nsA::foo()\n");
}
namespace subA {
void foo() {
printf( "nsA::subA::foo()\n");
printf( "calling nsB::foo()\n");
::nsB::foo(); // <--- calling foo() in namespace 'nsB'
}
}
}
int main()
{
nsA::subA::foo();
return 0;
}
Need more information to explain that error. The following code is fine:
#include <iostream>
namespace nsB {
void foo() { std::cout << "nsB\n";}
}
namespace nsA {
void foo() { std::cout << "nsA\n";}
namespace subA {
void foo() { std::cout << "nsA::subA\n";}
void bar() {
nsB::foo();
}
}
}
int main() {
nsA::subA::bar();
}
So, while specifying the global namespace solves your current problem, in general it is possible to refer to symbols in nsB without it. Otherwise, you'd have to write ::std::cout, ::std::string, etc, whenever you were in another namespace scope. And you don't. QED.
Specifying the global namespace is for situations where there's another nsB visible in the current scope - for instance if nsA::subA contained its own namespace or class called nsB, and you want to call ::nsbB:foo rather than nsA::subA::nsB::foo. So you'd get the error you quote if for example you have declared (but not defined) nsA::subA::nsB::theFunctionInNsB(...). Did you maybe #include the header for nsB from inside namespace subA?