Sorry for this silly question, but is there any way to restrict using directives to the current file so that they don't propagate to the files that #include this file?
No, there isn't, which is why you should not use using directives in header files, or any other file that you #include.
Perhaps wrapping the code to be included inside its own namespace could achieve the behavior
you want, since name spaces have scope affect.
// FILENAME is the file to be included
namespace FILENAME_NS {
using namespace std;
namespace INNER_NS {
[wrapped code]
}
}
using namespace FILENAME_NS::INNER_NS;
and in some other file
#include <FILENAME>
// std namespace is not visible, only INNER_NS definitions and declarations
...
Technically you should be able to import them to some internal namespace, and then make the things declared in that visible in the namespace meant for the user.
#ifndef HEADER_HPP
#define HEADER_HPP
#include <string>
namespace my_detail
{
using std::string;
inline string concatenate(const string& a, const string& b) { return a + b; }
}
namespace my_namespace
{
using my_detail::concatenate;
}
#endif
#include <iostream>
#include "header.hpp"
using namespace my_namespace;
int main()
{
std:: //required
string a("Hello "), b("world!");
std::cout << concatenate(a, b) << '\n';
}
Not sure if it is worth the trouble and how well it plays with "argument-dependent lookup".
Related
After writing my header file and trying to use it in the cpp.file. The compiler gives me an error when trying to redefine the function in header file.
I didn't face this problem the previous times I was using headers in a similar way. Maybe I initialize the Vector in a wrong way. Anyways here is the code:
#include <string>
#include <vector>
#include "lajitellut.h"
using namespace std;
namespace otecpp_lajitellut{
/*this is where the error appears*/
vector<string> lajitellut(int lkm, char*mjt[]){
vector<string> stringVector;
for(int i =0; i<lkm; i++){
stringVector.push_back(mjt[i]);
}
for(int i =0; i<lkm; i++){
for(int a = 0; a<lkm;a++){
if(stringVector[i] < stringVector[a]){
stringVector[i].swap(stringVector[a]);
}
}
}
return stringVector;
}
}
And here is the header file
#ifndef kissa
#define kissa
#include <string>
#include <vector>
namespace otecpp_lajitellut{
std::vector <std::string> lajitellut(int lkm, char* mjt[]) {
std::vector<std::string> stringVector;
return stringVector;
}
}
#endif // kissa
Put only the function declaration in the "lajitellut.h" header file:
#include <vector>
#include <string>
namespace otecpp_lajitellut {
std::vector<std::string> lajitellut(int, char*);
}
Put the function definition in the source "*.cpp" file:
#include <iostream>
#include <vector>
#include <string>
#include "lajitellut.h"
namespace otecpp_lajitellut {
std::vector<std::string> lajitellut(int lkm, char* mjt[]) {
// your code in here
}
}
int main(){
auto a = otecpp_lajitellut::lajitellut(10, "asd");
}
Note that definition is also a declaration. That being said you don't have a vector there. You have a function of type std::vector<std::string>. Don't use using namespace std;.
Ron is right.
Your function lajitellut() is already implemented in the .h file with the same signature. You can not create a double in the same namespace.
You can change the arguments or the type of the return value or change the namespace in the .cpp file.
For eg., when using OpenCV, we specify
using namespace cv;
But where does C++ look down to know where it is defined?
using namespace will not make everything declared in that namespace visible. It will expose only what translation unit "sees".
Consider following code
One.h
#pragma once
namespace ns
{
void function1();
}
Two.h
#pramga once
namespace ns
{
void function2();
}
main.cpp
#include "Two.h" // <-- included only Two.h
using namespace ns;
int main()
{
function2(); // <-- is a ns::function2() located in Two.h
function1(); // <-- error compiler does not know where to search for the function
return 0;
}
What happened here is the compiler created translation unit with all preprocessor directives resolved. It will look something like this:
namespace ns
{
void function2();
}
using namespace ns;
int main()
{
function2(); // <-- OK. Declaration is visible
function1(); // <-- Error. No declaration
return 0;
}
How does C++ know where to look for the namespace specified using using namespace …?
It doesn't.
When you use
using namespace cv;
the scope of search for names (of classes, functions, variables, enums, etc) is expanded. The names are searched in the cv namespace in addition to other scopes in which they are normally searched.
In C# it's simple to put all of the classes into an unique namespace. I understand how a namespace works in C++ at a simple level. But when comes to put many files together to appear as one namespace I get really confused.
It is something like this possible:
/* NetTools.cpp
blade 7/12/2014 */
using namespace std;
using namespace NetTools;
#include "NetTools.h"
int main()
{
cout << "testing" << endl;
return 0;
}
//####### EOF
/* NetTools.h
blade 12/7/2014 */
#ifndef NETTOOLS_H
#define NETTOOLS_H
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
namespace NetTools
{
}
#endif
// #### EOF
/* Commands.h
blade 7/12/2014 */
#include "NetTools.h"
#ifndef COMMANDS_H
#define COMMANDS_H
namespace NetTools
{
}
#endif
// ###### EOF
I'm separating every class declaration in its .h file and the implementation in its cpp file, but I want everything to be in the same namespace.
What you've shown works fine.
One fundamental property of namespaces is that if different files all declare things in a namespace with the same name, the compiler/linker know to put things together so you get one namespace containing everything that was defined in it from all the files.
For example:
// file a
namespace A {
class X;
}
// file b
namespace A {
class Y;
}
// file c
namespace A {
class Z;
}
...is mostly equivalent to:
// one file
namespace A {
class X;
class Y;
class Z;
}
The exception to this is anonymous namespaces. Anonymous namespaces are separated per-file. For example:
// file a
namespace {
void f();
}
// file b
namespace {
int f();
}
These don't conflict because each file has its own, unique anonymous namespace.
What you are doing is correct. There is a problem with your code here though:
/* NetTools.cpp
blade 7/12/2014 */
using namespace std;
using namespace NetTools; // put this AFTER #include "NetTools.h"
#include "NetTools.h"
int main()
{
cout << "testing" << endl;
return 0;
}
It works for using namespace std; (not sure why) but it won't work for namespaces you declare. The compiler needs to see them before you can start using them:
/* NetTools.cpp
blade 7/12/2014 */
#include "NetTools.h"
using namespace std;
using namespace NetTools; // now this should work
int main()
{
cout << "testing" << endl;
return 0;
}
Sidenote:
You should really put everything inside the include guard:
/* Commands.h
blade 7/12/2014 */
#include "NetTools.h" // this should really go after the include guards
#ifndef COMMANDS_H
#define COMMANDS_H
namespace NetTools
{
}
#endif
There is no need to #include "NetTools.h" twice (even if it is include protected).
/* Commands.h
blade 7/12/2014 */
#ifndef COMMANDS_H
#define COMMANDS_H
#include "NetTools.h" // like this
namespace NetTools
{
}
#endif
I have stumbled upon an unusual to me usage of using namespace directive:
Given a header file WeirdNamespace.h:
namespace WeirdNamespace
{
class WeirdClass
{
public:
int x;
void go();
};
}
I have a matching 'WeirdNamespace.cpp`:
#include "WeirdNamespace.h"
#include <iostream>
using namespace WeirdNamespace;
void WeirdClass::go()
{
std::cout << "Reached go?!" << std::endl;
}
The class is used as follows:
#include "WeirdNamespace.h"
int main(int argc, const char * argv[])
{
WeirdNamespace::WeirdClass c;
c.go();
}
Until now I have never seen the using directive used to avoid reopening the namespace in the cpp file or prefixing method names with the namespace name. Is it a correct usage of the directive? Are there any pitfalls specific to this scenario, except for the usual using namespace caveats?
You might do:
namespace WN = WeirdNamespace;
WN::WeirdClass c;
Now, I got the question! The above is no answer.
Quoting from [7.3.4] 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."
Hence your definition in the source without enclosing it in the namespace is fine.
Yes it is valid but there is a pitfall:
using namespace NamespaceName will make available all the names in NamespaceName.
So instead you can use using to use only the class name:
#include <iostream>
#include "WeirdNamespace.h"
using WeiredNamespace::WeiredClass;
void WeiredClass::go() {
// ...
}
I want to put a namespace alias (ie namespace A = B::C) in a header file so I can use it in source files, but the compiler just tells me that its "not a namespace name". Any thoughts?
This is a very simplified axample of what I'm trying to do...
header file:
namespace A{
namespace B{
int getInt();
}
}
namespace AB = A::B;
source file:
#include "header_file.h"
#include <iostream>
int AB::getInt(){ // Error "AB is not a namespace name"
return 123;
}
You need to include the file that declares the namespace in the header file or as the comments say do this:
namespace B { namespace C { } }
namespace A = B::C;
At the point where you create the alias, the compiler must have already seen the aliased namespace.
Therefore, you must #include a file that contains said namespace or you must do this:
// "Forward Declaring" the namespace
namespace B { namespace C { } }
namespace A = B::C;