I have a problem with including header files in C++. As far as I know, it's not a good design to put using namespace std inside header but I got some error when I try to remove it. Here is my code in header file :
#include <iostream>
#include <string>
//using namespace std;
class Messages
{
public:
Messages(string sender, string recipient,int time);
void append();
string to_string();
private:
int time;
string sender;
string recipient;
string text;
};
I did include <string>. However, If I don't use namespace std, all my strings show errors. I do not want to add using namespace std in header file because it's a bad design. So how do I fix it?
Thanks in advance.
Just write std::string everywhere.
#include <iostream>
#include <string>
//using namespace std;
class Messages
{
public:
Messages(std::string sender, std::string recipient,int time);
void append();
std::string to_string();
private:
int time;
std::string sender;
std::string recipient;
std::string text;
};
Just as a rule of thumb: whenever (even in .cpp files) you are using any of the data types or algorithms from the Standard Library, just prefix it with std::. It's brief enough to type, and it will save you a world of pain.
There are some reasons for advanced users to use using declarations at function scope, e.g. when you want to overload a function (e.g. swap) from the Standard Library to work with your own data types (inside their own namespaces). See e.g. this Q&A on how that works.
The class string is declared inside the namespace std. You have three ways of addressing a class that's inside a different namespace:
By always writing <namespace>::<class>
By explicitly declaring that any reference to <class> actually means 1. above: using <namespace>::<class>;.
By declaring that any reference to a <class> that could not be resolved in the current namespace should also be looked up in an additional namespace: using namespace <namespace>;
Those are sorted in descending order of expressiveness. While 1. is perfectly clear wherever written, 3. can require some looking-up and scratching of heads if you are not familiar with the (possible multiple) namespaces used.
These are also sorted in descending order of typing involved, which is why some people (and especially textbooks) opt for 3.
However, you should never use using ... in a header file, because you are not only messing with the namespace resolution inside your header, but also with that of everyone including your header. This results in namespace collisions, strange errors depending on the order of includes and lots of other headaches. Just don't.
And generally speaking, while there is some pro and con involved with options 1. and 2. in implementation files, option 3. is simply offensive to anyone having to work with your source later on.
Related
this is my first question here, I've searched it all over for a long time yet no solution.
I'm using QUadprog++ to solve a quadratic problem. When I use it in a test alone, it was alright. But when I implement it into my project, which contains Eigen, the Eigen operations will have errors like "Matrix A has no member named ‘lu_inverse’". If I comment the header files of Quadprog++ (Array.hh and Quadprog++.hh) out, the errors just disappear. So I assume that it was a conflict error between the header files of Eigen and Quadprog++. Does anyone have some clue? Thanks in advance!
You can also switch to one of QuadProgpp versions which can work with Eigen types directly: https://github.com/asherikov/QuadProgpp, https://www.cs.cmu.edu/~bstephe1/eiquadprog.hpp; or try an alternative implementation of the same algorithm (also Eigen based) https://github.com/asherikov/qpmad.
if your using namespace quadprogpp; then dont. your different libraries have the same typenames and thats causing the errors you have. It may be a few more characters to type quadprogpp::someFunction(); but its worth it. This is also why you shouldn't ever put a using namespace in a header ever. Its because you pollute all files that include that header with the namespace symbols and name conflicts can ensue which is the same kind of error your having right now.
the Quadprog library is in it's own namespace.
#if !defined(_ARRAY_HH)
#define _ARRAY_HH
#include <set>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
namespace quadprogpp {
enum MType { DIAG };
template <typename T>
class Vector
notice how just after the #includes there is a decleration of namespace quadprogpp{} and everything that is defined in its enclosing brackets will be defined in scope to quadprogpp, so to use any of this library you have to prefix eveything with the namespace name. this is no different than using things from the standard library. I'm quite sure you've written the standard c++ hello world
#include<iostream>
int main()
{
std::cout << "hello world!" << std::endl;
return 0;
}
cout and endl being part of namespace std have to be prefixed with std:: to access them. Many new programmers to c++ dislike this and one of the very first things they google is how to not have to type out namespaces.
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
the next thing new programmers often do is learn to place their definitions in header files and their program logic in cpp files. Thats when they commit the next common mistake.
#ifndef MYHEADER
#define MYHEADER
#include<string>
#include<vector>
#include<iostream>
using namespace std; //Never do this in a header.
doing that pollutes all of your code with everything in the standard library. That may seem like a trivial thing but when you start using another library or perhaps you create your own type that has the same name as things in the standard library that causes name collisions.
That's when the compiler simply cant reason about which Vector you want. But both Quadprog.hh and Array.hh in Quadprog++ are wrapped in namespace quadprogpp to specifically prevent name collision, which is the whole purpose of namespaces. So there is somewhere in your code, likely a header file, where you've made the statement of using namespace quadprogpp;, or some other namespace that defines an Array type, and the compiler can't deduce which type your referring to in your code.
Other than removing your using namespace statements you can also prefix a typename with its namespace qualifer to disambiguate which type your talking about. In your case I'm confident your Array should be declared as quadprogpp::Array arraynamme; rather than simply Array arrayname;
So I'm learning to use a class .h and .cpp files in my program that reads a file containing information about a bank account. Initially the code worked fine, however after creating the .h and .cpp class files, things don't work so smoothly anymore, as I'm getting strange errors that don't make sense to me.
This is my MAIN cpp file:
#include "Bankaccount.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{ string fileName;
cout << "Enter the name of the data file: ";
cin>>fileName;
cout<<endl;
bankAccount object(fileName);
return 0;
}
This is my Bankaccount.h file
#ifndef BANKACCOUNT_H
#define BANKACCOUNT_H
#include <iostream>
#include <fstream>
#include <string>
class bankAccount
{
public:
bankAccount(string n);
bankAccount();
private:
ifstream sourceFile;
}
And lastly this is the Bankaccount.cpp file
#include "Bankaccount.h"
#include <iostream>
#include <fstream>
#include <string>
bankAccount::bankAccount(string n)
{
sourceFile.open(n.c_str());
}
Which is now generating these errors:
include\Bankaccount.h|13|error: expected ')' before 'n'|
include\Bankaccount.h|18|error: 'ifstream' does not name a type|
include\Bankaccount.h|14|note: bankAccount::bankAccount()|
include\Bankaccount.h|14|note: candidate expects 0 arguments, 1 provided|
include\Bankaccount.h|4|note: bankAccount::bankAccount(const bankAccount&)|
include\Bankaccount.h|4|note: no known conversion for argument 1 from 'std::string {aka std::basic_string}' to 'const bankAccount&'|
I think it might be an issue with the headers? I went a little bit crazy and put all of my relevant headers on each file trying to get it to work.
using namespace std;
This is considered a bad programming practice, and you will do yourself a favor if you forget that this is actually a part of C++ language. Although there are proper situations where one would employ using namespace, this should be avoided until one has a much better technical understanding of C++, its structure, and its grammar; in order to recognize and understand when this can be used correctly (if at all).
In your main() you have:
string fileName;
There is no such class in the C++ library whose name is string. The class's correct name is std::string; however by shoving using namespace std; a few lines above, you end up blissfully unaware of this basic, fundamental fact.
Now, after you understand this, let's go back and look at your header file:
ifstream sourceFile;
Well, there's no such class in the C++ library called ifstream, either. The class's proper name is std::ifstream. All classes and templates from the C++ library exist in the std namespace.
However, because when you #included the header file your using namespace std; alias is not yet defined, your compiler doesn't recognize the class name, and you get this compilation error as a reward.
The solution is not to cram a using namespace std; in your header file. That will simply lead to more chaos and confusion. The proper fix is:
Remove using namespace std; from your code, completely.
Use full names of all classes from the C++ library, everywhere. Replace all references to string, ifstream, and everything else, with their actual class names: std::string, std::ifstream, and so on. Get into the habit of explicitly using the std namespace prefix every time. It might seem like a bother at first, but you'll quickly pick up the habit before long, and you won't think of it twice.
And you'll never be confused by these kinds of compilation errors ever agin.
In C, if I use #include "someFile.h", the preprocessor does a textual import, meaning that the contents of someFile.h are "copy and pasted" onto the #include line. In C++, there is the using directive. Does this work in a similar way to the #include, ie: a textual import of the namespace?
using namespace std; // are the contents of std physically inserted on this line?
If this is not the case, then how is the using directive implemented`.
The using namespace X will simply tell the compiler "when looking to find a name, look in X as well as the current namespace". It does not "import" anything. There are a lot of different ways you could actually implement this in a compiler, but the effect is "all the symbols in X appear as if they are available in the current namespace".
Or put another way, it would appear as if the compiler adds X:: in front of symbols when searching for symbols (as well as searching for the name itself without namespace).
[It gets rather complicated, and I generally avoid it, if you have a symbol X::a and local value a, or you use using namespace Y as well, and there is a further symbol Y::a. I'm sure the C++ standard DOES say which is used, but it's VERY easy to confuse yourself and others by using such constructs.]
In general, I use explicit namespace qualifiers on "everything", so I rarely use using namespace ... at all in my own code.
No, it does not. It means that you can, from this line on, use classes and functions from std namespace without std:: prefix. It's not an alternative to #include. Sadly, #include is still here in C++.
Example:
#include <iostream>
int main() {
std::cout << "Hello "; // No `std::` would give compile error!
using namespace std;
cout << "world!\n"; // Now it's okay to use just `cout`.
return 0;
}
Nothing is "imported" into the file by a using directive. All it does is to provide shorter ways to write symbols that already exist in a namespace. For example, the following will generally not compile if it is the first two lines of a file:
#include <string>
static const string s("123");
The <string> header defines std::string, but string is not the same thing. You haven't defined string as a type, so this is an error.
The next code snippet (at the top of a different file) will compile, because when you write using namespace std, you are telling the compiler that string is an acceptable way to write std::string:
#include <string>
using namespace std;
static const string s("123");
But the following will not generally compile when it appears at the top of a file:
using namespace std;
static const string s("123");
and neither will this:
using namespace std;
static const std::string s("123");
That's because using namespace doesn't actually define any new symbols; it required some other code (such as the code found in the <string> header) to define those symbols.
By the way, many people will wisely tell you not to write using namespace std in any code. You can program very well in C++ without ever writing using namespace for any namespace. But that is the topic of another question that is answered at Why is "using namespace std" considered bad practice?
No, #include still works exactly the same in C++.
To understand using, you first need to understand namespaces. These are a way of avoiding the symbol conflicts which happen in large C projects, where it becomes hard to guarantee, for example, that two third-party libraries don't define functions with the same name. In principle everyone can choose a unique prefix, but I've encountered genuine problems with non-static C linker symbols in real projects (I'm looking at you, Oracle).
So, namespace allows you to group things, including whole libraries, including the standard library. It both avoids linker conflicts, and avoids ambiguity about which version of a function you're getting.
For example, let's create a geometry library:
// geo.hpp
struct vector;
struct matrix;
int transform(matrix const &m, vector &v); // v -> m . v
and use some STL headers too:
// vector
template <typename T, typename Alloc = std::allocator<T>> vector;
// algorithm
template <typename Input, typename Output, typename Unary>
void transform(Input, Input, Output, Unary);
But now, if we use all three headers in the same program, we have two types called vector, two functions called transform (ok, one function and a function template), and it's hard to be sure the compiler gets the right one each time. Further, it's hard to tell the compiler which we want if it can't guess.
So, we fix all our headers to put their symbols in namespaces:
// geo.hpp
namespace geo {
struct vector;
struct matrix;
int transform(matrix const &m, vector &v); // v -> m . v
}
and use some STL headers too:
// vector
namespace std {
template <typename T, typename Alloc = std::allocator<T>> vector;
}
// algorithm
namespace std {
template <typename Input, typename Output, typename Unary>
void transform(Input, Input, Output, Unary);
}
and our program can distinguish them easily:
#include "geo.hpp"
#include <algorithm>
#include <vector>
geo::vector origin = {0,0,0};
typedef std::vector<geo::vector> path;
void transform_path(geo::matrix const &m, path &p) {
std::transform(p.begin(), p.end(), p.begin(),
[&m](geo::vector &v) -> void { geo::transform(m,v); }
);
}
Now that you understand namespaces, you can also see that names can get pretty long. So, to save typing out the fully-qualified name everywhere, the using directive allows you to inject individual names, or a whole namespace, into the current scope.
For example, we could replace the lambda expression in transform_path like so:
#include <functional>
void transform_path(geo::matrix const &m, path &p) {
using std::transform; // one function
using namespace std::placeholders; // an entire (nested) namespace
transform(p.begin(), p.end(), p.begin(),
std::bind(geo::transform, m, _1));
// this ^ came from the
// placeholders namespace
// ^ note we don't have to qualify std::transform any more
}
and that only affects those symbols inside the scope of that function. If another function chooses to inject the geo::transform instead, we don't get the conflict back.
I'm trying to use namespaces in my code so I have a header file that looks like this :
#include <string>
namespace AppNamespace
{
class A
{
std::string name;
};
}
When I try to compile this, it says "'string' is not a member of AppNamespace::std". If I remove the std:: in front of string, or if I write ::std::string name, then it will compile fine.
This is of course a simplified example, I have many header files and not all of them show this behavior. I am not sure what can cause this, I thought that the compiler would always try the global namespace as well.
I am currently using Visual Studio 2012 if this matters.
This is of course a simplified example, I have many header files and not all of them show this behavior. I am not sure what can cause this, I thought that the compiler would always try the global namespace as well.
At some point you must have something like this:
namespace AppNamespace
{
#include <string> // or #include "my_header" which in turn includes <string>
class A
{
std::string name;
};
}
The #include directive does not respect namespaces. You need to move them all out to the global namespace scope, or each (possibly nested) inclusion of a standard header will cause undefined behavior in the form of creating a nested namespace std.
Using:
using namespace std;
#include <iostream>
#include "test_header.h"
int main() ...
The code compiles either way with your above example as a header.
Moving
using namespace std;
below the header file (in my case test_header.h) will cause it to fail if I don't use std::string.
Is that the problem you are having?
I know this is quite a ridiculous question but this is quite confusing and irritating, as something that should work simply is not. I'm using Code Blocks with the GCC compiler and I am trying to simply create a string variable in my class
#ifndef ALIEN_LANGUAGE
#define ALIEN_LANGUAGE
#include <string>
class Language
{
public:
private:
string str;
};
#endif
Strange enough, my compiler halts me with an error saying this:
C:\Documents and Settings\...|11|error: `string' does not name a type|
||=== Build finished: 1 errors, 0 warnings ===|
For some reason, it is unable to find the class "string" which for some reason, my main.cpp is able to detect "#include " while my language class is not able for some reason.
This is the main I wrote quickly just to see it main itself is able to see the string file:
//main.cpp
#include <iostream>
#include <string>
#include "alien_language.h"
using namespace std;
int main()
{
string str;
return 0;
}
Does anyone know what's going on?
using namespace std;
That's what's going on.
You don't have std:: prefixing the string in your class. Everything in the standard library is in the namespace std.
It is generally regarded as bad practice to use using namespace std;, by the way. For more information on why and what to do instead, check out this question: Using std Namespace.
The string class is defined in the std namespace. You should chenge the class to this:
class Language
{
public:
private:
std::string str;
};
It is also possible, but not recommended to add this to the top of the header file:
using namespace std;
string is in namespace std, and you need to qualify it fully inside your header file:
#include <string>
class Language
{
public:
private:
std::string str;
};
Do not use using namespace std; or similar in header files.
You should refer to it as std::string;
It looks to me like you're missing the all-important (with a hint of sarcasm) using namespace std; line. Either add that in before your class, or explicitely use std::string str. I'd recommend against adding the using namespace std; line in a header file, as it would pollute the mainspace for any file that includes it.
The string class in standard C++ is in std namespace. Write something like
using std::string; in your header or fully qualify it as std::string in your header.
Beware that using namespace std; in header is a bad practice (read here).