How can I call a namespace inside a function? - c++

Something interesting and wrong about my code.
#include <iostream>
void func(){
using namespace std;
}
main(){
func(); //Here the function will introduce the (using namespace std declaration) in the code
cout << "Hello World!";
return (0);
}
When compiled the error message is shown:
atizva#atizva:~/Documents/C++/Programs$ g++ -o func function_call.cpp
function_call.cpp: In function ‘int main()’:
function_call.cpp:7:2: error: ‘cout’ was not declared in this scope
cout << "Hello World!";
^~~~
function_call.cpp:7:2: note: suggested alternative:
In file included from function_call.cpp:1:0:
/usr/include/c++/7/iostream:61:18: note: ‘std::cout’
extern ostream cout; /// Linked to standard output
^~~~
I don't understand why the function 'func()' doesn't call the tag: 'using namespace std' appropriately.

To fix this, you would have to move using namespace std; outside of func(). The reason this fails in your current code is that using declaration only applies within the scope that it is called (in this case func()). So once you exit func(), you lose the effects of using namespace std;

You assume that namespaces are enabled at runtime, but namespaces are only meaningful at compile time. What you are doing is to limit the use of std to the scope of the function func(). That is, it allows you to type
cout
inside that function, but not elsewhere.

Related

Overload not considered even though it looks like a better match

This is rejected by both gcc (live on godbolt) and clang:
#include <string>
namespace
{
std::string
to_string(char const (&str) [14])
{ return str; }
}
void f()
{
using std::to_string;
char const hello[14] = "Hello, World!";
(void) to_string(hello);
}
The compiler considers each of the std::to_string overloads and conclude with:
error: no matching function for call to 'to_string(const char [14])'
If I remove using std::to_string, my overload is considered and called. Why? How to fix it (other than removing the using)?
The scope of the using declaration matters. It's a proper declaration, so name hiding takes effect. Inside the function the global scope version isn't visible. You need to reintroduce it:
using ::to_string;
using std::to_string;
This using declaration
using std::to_string;
hides the declaration in the global namespace. So the compiler does not see the function ::to_string.
So you have to write
using std::to_string;
using ::to_string;
And make the unnamed namespace inline.
inline namespace
{
// ...
}

Overloading a function defined in a namespace

Why is the following code illegal?
#include <iostream>
using namespace std;
namespace what {
void print(int count) {
cout << count << endl;
}
}
void what::print(const string& str) {
cout << str << endl;
}
int main() {
what::print(1);
what::print("aa");
return 0;
}
The error I get when compiling with clang and -std=c++14 is
error: out-of-line definition of 'print' does not match any declaration in namespace 'what'
I know the fix to the problem but I am wondering why the compiler thinks that I am trying to define the function (print) instead of overload it.
The reason it is not working for you is because the syntax
void what::print(const string& str)
is basically saying
inside the what namespace, define the print function here
If you want to define a function outside of its namespace, you must declare it in the namespace beforehand.
§13.1 of the standard states, "When two or more different declarations are specified for a single name in the same scope, that name is said
to be overloaded."
Overloads of a function must be in the same scope of each other. It is just how the language works.

Compile error:... was not declared in this scope

I'm a neophyte of C++ programmation. I have to implement a program witch calculates the pseudoinverse of a matrix. As the Eigen tutorial suggests, I have written a code like this:
#include <stdio.h>
#include <stdlib.h>
#include <Core>
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/SVD>
#include <Eigen/Eigen>
using namespace Eigen;
using namespace std;
void pinv(MatrixXf& pinvmat)
{
ei_assert(m_isInitialized && "SVD is not initialized.");
double pinvtoler=1.e-6; // choose tolerance
SingularValuesType m_sigma_inv=m_sigma;
for ( long i=0; i<m_workMatrix.cols(); ++i) {
if ( m_sigma(i) > pinvtoler )
m_sigma_inv(i)=1.0/m_sigma(i);
else m_sigma_inv(i)=0;
}
pinvmat = (m_matV*m_sigma_inv.asDiagonal()*m_matU.transpose());
}
int main()
{
MatrixXf A(3,2);
A<<1,2,3,4,5,6;
pinv(A);
cout << "pinv =" << endl << A << endl;
return 0;
}
If I try to compile it I'll get the errors:
tut_eigen/pinv.cpp: In function ‘void pinv(Eigen::MatrixXf&)’:
tut_eigen/pinv.cpp:18:14: error: ‘m_isInitialized’ was not declared in this scope
tut_eigen/pinv.cpp:18:58: error: ‘ei_assert’ was not declared in this scope
tut_eigen/pinv.cpp:20:4: error: ‘SingularValuesType’ was not declared in this scope
tut_eigen/pinv.cpp:20:23: error: expected ‘;’ before ‘m_sigma_inv’
tut_eigen/pinv.cpp:21:22: error: ‘m_workMatrix’ was not declared in this scope
tut_eigen/pinv.cpp:22:19: error: ‘m_sigma’ was not declared in this scope
tut_eigen/pinv.cpp:23:19: error: ‘m_sigma_inv’ was not declared in this scope
tut_eigen/pinv.cpp:24:22: error: ‘m_sigma_inv’ was not declared in this scope
tut_eigen/pinv.cpp:26:15: error: ‘m_matV’ was not declared in this scope
tut_eigen/pinv.cpp:26:22: error: ‘m_sigma_inv’ was not declared in this scope
tut_eigen/pinv.cpp:26:47: error: ‘m_matU’ was not declared in this scope
Why?? They are not declared in SVD file?
I suspect you talk about this "tutorial" which isn't so much a tutorial but an FAQ assuming you know a bit about the library already (it would be helpful if you link to your sources of information, BTW).
What this says is that you can add the pinv() method to the SVD "from the outside". I assume they mean that you can derive from SVD and provide the pinv() method in your derived class. Just typing the function somewhere doesn't give the compiler the necessary context to determine where referenced names are located.

Namespace using declaration (C++ Primer - Stanley Lipmann)

Anyone can help me to understand this statement found in chapter 3 (Library Types) by Stanley Lipmann?
"Using an unqualified version of a namespace name without a using declaration is an error, although some compilers may fail to detect this error"
I'm having such hard time understanding the semantics of his sentence (english).
Is he trying to say something like the below scenario?
int main() {
xx::yy
}
where xx is a namespace not defined using the "using" statement and yy is a member?
Example:
cout is a name of the std namespace. The unqualified name is cout. The qualified name is std::cout. It is an error to use the unqualified name(cout) without a using declaration beforehand. You can use either one of the two following declarations:
// This brings in the entire std namespace
using namespace std;
OR
// This only brings in cout. You would still need to qualify other names,
// such as cin, endl, etc...
using std::cout;
What he's saying is that the following code should not compile:
#include <iostream>
void foo() {
cout << "This is an error!" << endl;
}
The cout and endl names are not defined right now. They're declared as std::cout and std::endl, and in order to use them, you can do one of a few things:
#include <iostream>
void foo() {
std::cout << "This, I think, is the best way to do it." << std::endl;
}
Using the fully qualified name prevents collisions later on: you'll never have something else called std::cout.
#include <iostream>
void foo() {
using std::cout;
using std::endl;
cout << "This is pretty good." << endl;
}
Having the using statements specify the exact names you're using, and having the using statements in the function, can save some typing and makes collisions pretty unlikely.
#include <iostream>
using namespace std;
void foo() {
cout << "This works, but isn't good." << endl;
}
Importing the entire std namespace makes it pretty likely that you'll end up having a function named the same as an std function.. You might discover that as soon as you write it, or you might write your function and then later include the header file with the std version of the function, at which point your application will mysteriously break.
A namespace name is the name of a namespace.
namespace A {
}
namespace B = A;
The statement says that using a namespace name without a using declaration is an error. But that's not true: The above code is fine, still using the namespace-name A as an unqualified name.
Probably it should say the following, to convey its meaning
"Using an unqualified version of a namespace member name without a using declaration
outside the scope of the namespace is an error, although some compilers may fail to
detect this error"
Mentioning the scope is important. The following, for example, is fine too, even though it uses the unqualified version of a namespace member name
namespace A {
int x;
int &y = x; // x is an unqualified name
}
Books should be careful to try and not use slippery language. And even outside the scope of the namespace, the above sentence is not entirely correct because you can also extend the scope of x by a using directive. Using declarations aren't the only way to name a namespace member outside the namespace using an unqualified name.

"nice" keyword in c++?

So I was doing some simple C++ exercises and I noticed an interesting feat. Boiled down to bare metal one could try out compiling the following code:
class nice
{
public:
nice() {}
};
int main()
{
nice n;
return 0;
};
The result is a compilation error that goes something like this:
<file>.cpp: In function ‘int main()’:
<file>.cpp:11: error: expected `;' before ‘n’
<file>.cpp:11: warning: statement is a reference, not call, to function ‘nice’
<file>.cpp:11: warning: statement has no effect
And this was using regular g++ on Max OS X, some of my friends have tried in on Ubuntu as well, yielding the same result.
The feat seems to lie in the word "nice", because refactoring it allows us to compile. Now, I can't find the "nice" in the keyword listings for C++ or C, so I was wondering if anyone here had an idea?
Also, putting
class nice n;
instead of
nice n;
fixes the problem.
P.S. I'm a relative C++ newbie, and come from the ActionScript/.NET/Java/Python world.
Update:
Right, my bad, I also had an
#include <iostream>
at the top, which seems to be the root of the problem, because without it everything works just fine.
Maybe the problem is somehow caused by function nice in libc. It is similar to trying to name your class printf.
using namespace std, by any chance?
Edit:
The standard says that standard headers define all their symbols in namespace std (see 17.4.1.2.4).
A footnote, however, also says that the <.h> variants dump their names into the global namespace - but of course no one should be using these ;)
It is a namespace problem but not with namespace std. The header <iostream> is pulling in <unistd.h>
If you try
class nice
{
public:
nice() {};
};
int main(int argc, char *argv[])
{
nice n;
return 0;
}
there is no problem.
Simply add
#include <unistd.h>
and you will get the "expected ‘;’ before ‘n’" error. Namespace std does not enter the picture.
So the solution is the same as before - put class nice in its own namespace and it will not clash with the global ::nice().
Try this version:
#include <iostream>
namespace test
{
class nice
{
public:
nice() {}
};
};
using namespace std;
int main()
{
test::nice n;
cout << "well I think this works." << endl;
return 0;
}
In this case I've defined my own namespace test. Doing so, I can use whatever class names I like, including functions already defined like printf. The only things I can't re-use are reserved words like int or namespace.
Note: if you say:
using namespace test;
As well and refer to nice alone, you'll get this error:
nice.cpp: In function ‘int main()’:
nice.cpp:18: error: reference to ‘nice’ is ambiguous
/usr/include/unistd.h:593: error: candidates are: int nice(int)
nice.cpp:7: error: class test::nice
Which I think explains nicely what's going on - nice now exists in two namespaces and the compiler can't work out which one you mean.
It works fine for me. Did you try the exact code you posted?
extern "C"
{
#include <unistd.h>
}