I am new to C++ but as I understand it is bad to use the using namespace keywords in header files. I am trying to write a template class, and have read that the definition of the template class member functions must be in the header as well as all the template code must be in the same place. My issue is, it can get tedious writing all of the code without the using namespace keywords. For example at the moment I have:
#ifndef RANDOMTREE_H_
#define RANDOMTREE_H_
template<class T>
class RandomTree {
private:
typedef double (*funcion_ptr) (T, T);
public:
RandomTree(std::vector<T> data, std::vector<funcion_ptr>){
...
}
void train_tree();
};
#endif /* RANDOMTREE_H_ */
But I intend to use some boost methods etc inside the function bodies and would like to know if there is a way to not have to keep typing the prefixes std:: and boost::
Well, this code looks pretty good to me.
It's not a big deal to write them once in the declarations.
In the definitions, if you want to omit writing ns::, you may have using namespace ns; inside a function.
Or, just include some names, like: using ns::name;. But I wouldn't do that.
You can also use typedef:
typedef std::string string;
It has the advantage not using using
The options to not having to type the qualifications (std::, boost::) is having using directives. If there was any other way (there isn't in this case), it would carry around the same problem as having the using directives, so either alternative would be equally bad.
Note that using doesn't have to be applied to a namespace. You can, for example, do:
using std::string;
and then directly use string, but this also isn't recommended.
Related
I got some confusion in mind between what my professor told us at uni and what I have read in Stroustrup's book.
We all know that a C++ header is basically a collection of
declarations (defined in a file.h) and they can contain for example a
collection of classes. They are very useful because they give us a
lot of features stored in a single space
A namespace is someting invented to organize classes, functions,
types (...) in a part of the program without defining a type.
I cannot see the concrete difference here when I have to create a project.
If I had (for example) to make a program that solves equations of various degrees, I'd put the classes that I need in a single file. For example I am going to place in equations.h all this stuff: class secondDeg, class thirdDeg, class fourthDeg and so on.
Why should I use a namespace then?
The answer (I guess) is: because you can give a name for a better organization (see std::cin). But in this case I should
Create equations.h (or whatever)
Create a namespace called eq for example
Put my classes in the namespace
Is this really necassary? Cannot I only use a header file and put all my classes inside?
Why should I use a namespace then?
A namespace can encompass multiple headers, eg., namespace std encompasses definitions from <vector> <list> etc.
You can define your own namespace to not pollute the global namespace and avoid conflicts. It's good practice to limit the namespace to the minimum for what you need, therefore using namespace std; is generally avoided.
Is this really necassary?
It depends. The better and more clear option would be to embed your declarations in a namespace.
Cannot I only use a header file and put all my classes inside?
Sure you can, just avoid any clashes with symbols declared in the global (::) scope and refrain from using namespace <xxx>; in header files.
You seem to be conflating two distinct concepts. A header is a file, typically used to contain declarations. It can contain function declarations, classes, templates, etc.
A namespace is a means of defining a scope, within which all items declared are unique. This allows you to use function and class names that might otherwise clash with names in the standard. For example
namespace mystuff
{
class list { };
};
Your list will not conflict with std::list.
Namespaces can and should be used in header files to declare the classes and such that are part of that namespace. However, as noted by others, using a 'using' directive in a header file is discouraged because it can create the very name conflicts the namespace was intended to solve.
I have a library "myLibrary" that depends on "Blibrary". I want the users of "myLibrary" to not know that dependency. I'm trying to hide it without luck, here is an example of what I have right now.
#include <game/Object.h>
#include <Blibrary/Component.hpp> // How can I remove this library header?
// forward declaring it? it's a template..
namespace myLibrary {
template<typename T>
struct Component: public Object, public Blibrary::Component<T>
{
};
//template<typename T>
//class Blibrary::Component<T>; //I Tried something like that..
//template<typename T>
//struct Component: public Object
//{
// Blibrary::Component<T> * m_impl;
//};
}
//I want the user do this when declaring a usermade component:
#include <game/Component.h> //<-- but without the Blibrary include dependency
class Position: public myLibrary::Component<Position>
{
float x, y, z;
};
Is it possible to hide implementation of template class?
No, it is not. A class template must be defined completely in header files. You can only obfuscate the implementation by using multiple layers of header files and using helper class names and helper function names that are obfuscations of the highest level, user visible classes.
However, as #vsoftco noted in a comment, you can hide it if you use it only for some specific types, in which case you can do explicit instantiation, export the template and implement it in the .cpp.
A nice idea from this similar question was to put the implementation classes/functions you want to "hide" into another level of namespace.
You can even separate them into a different .h file to be included at the top.
Now, of course this is incapable of really hiding them programmatically from anywhere you include the header, but it does prevent them going into the scope, and means that it would not be possible to use them without explicitly dereferencing that additional namespace.
So for example you'd have namespace mylibrary for your library, and something like mylibrary::priv or mylibrary::impl, for example, for the things you're "hiding".
I've implemented a policy-based class. For the moment, the class template and its policy classes are declared in a namespace called utility.
The problem I face is the verbosity of the resulting code. Client code looks like that:
utility::MyTool<utility::AFirstPolicy, utility::ASecondPolicy>
my_function(utility::MyTool<utility::AnotherFirstPolicy, utility::AnotherSecondPolicy>);
Not very readable, as you can see. I would like to get something closer from:
MyTool<AFirstPolicy, ASecondPolicy>
my_function(MyTool<AnotherFirstPolicy, AnotherSecondPolicy>);
I'm wondering what the good practice is in such a case. Here is what I can think of:
Typedef
The most obvious solution. Not very convenient for me because the policies can differ from function to function an bring important information on the function usage. I would like them to appear directly in the function prototype. Moreover, it introduces many type names in several namespaces.
Using directive
Put a using namespace utility; or using utility::MyTool; using utility::AFirstPolicy;, etc. in my file.
The tool is often used in header files from other namespaces, which makes using-directives not very suitable.
Policy classes in global namespace
I don't like this approach especially as policy classes often have vague names that make sense only in their context.
Macro
Use something as
#define MY_TOOL(pcy1, pcy2) utility::MyTool<utility::##pcy1, utility::##pcy2>
to transform the previous code to
MY_TOOL(AFirstPolicy, ASecondPolicy)
my_function(MY_TOOL(AnotherFirstPolicy, AnotherSecondPolicy));
I'm not sure this is more readable. It works only for a fixed number of policies (this is my case: always 2, no default setting) and it does not work if the policy classes themselves take template parameters.
Which of the previous approaches would you recommend to me? Are there "best practices"? Another idea?
If you have a my_function(utility::MyTool<...>), then I would say that my_function belongs to the interface of the class template utility::MyTool<...>. In other words, my_function itself belongs to the namespace utility.
This means that you can write code in the desired shorthand form:
namespace utility {
typedef MyTool<AFirstPolicy, ASecondPolicy> SomeTool;
my_function(SomeTool);
}
You can read more about interfaces and namespaces in this old column "What's In a Class" by Herb Sutter.
Note that even if you want to use functions in other namespaces with classes from namespace utility, you can still reopen that namespace and define the policy class right there and do something like
// SomeHeader.hpp
namespace bla {
// your classes and functions
}
// reopen namespace utility
namespace utility {
typedef MyTool<AFirstPolicy, ASecondPolicy> SomeTool;
}
namespace bla {
typedef utility::SomeTool BlaTool; // or using-declaration
my_function(BlaTool);
}
This is of course more verbose than defining my_function inside the utility namespace, but at least you can assemble all the various policies without too much typing.
I need to add a few methods to c++'s class.
I'm creating a new class using inheritance called "Super_list" that will inherit all of list's methods and allow my to add my own.
#ifndef SUPER_LIST_H
#define SUPER_LIST_H
#include "my_containter.h"
#include <list>
using namespace std;
class My_Container;
class Super_list: public list<My_Container>
{
public:
void new_func1();
void new_func2();
void new_func_3();
};
#endif
This is where I'm using my newly made class:
#ifndef my_container_H
#define my_container_H
#include <list>
#include "super_list.h"
using namespace std;
class Super_list;
class My_container
{
private:
Super_list buddy;
};
#endif
I'm getting a bunch of error relating to the inheritance not being done correctly.
I would appreciate any help or other ideas from completing this task.
Thanks :)
You have a cyclic dependency: MyContainer needs so know about Super_list and vice versa. You need to find a way to break this dependency. Note that in your code, the forward declarations are completely superfluous.
Note also that standard library containers aren't designed to be inherited from publicly.
Concerning the dependency, you need to modify at least one of your classes such that it does not need the full definition of the other. Pretending for a moment that publicly inheriting from std::list is OK, then the only option would be for My_Container not to need the full definition of SuperList by having it hold a (preferably smart) pointer:
class My_container
{
private:
Super_list* buddy;
};
This would allow you to remove the super_list.h include.
One unrelated warning: it is not good to put using namespace std in header files, since it will impose that using directive on all code that, directly or indirectly, includes your header. This can lead to all kind of trouble. I usually go farther and say you shouldn't use it anywhere. Not everyone agrees with me on that one.
I would ask if you really do need to inherit to gain additional functionality. Try using a list as a member of your class. Not only will it make your class easier to change, but it means that code that uses your class won't care about whether its a list or not.
Here is more information
Can't say much without the error messeages.
1) You probably want to define some constructors in Super_list which forward their arguments to the std::list constructors.
2) Every time I tried to do something like this (or worked with something like this) it turned out to be a BAD idea. To keep incapsulation, what you probably want is some global functions:
template<class T>
new_func1(std::list<T> &l)
template<class T>
new_func2(std::list<T> &l)
etc.
I want to remove, if possible, the includes of both <vector> and <string> from my class header file. Both string and vector are return types of functions declared in the header file.
I was hoping I could do something like:
namespace std {
template <class T>
class vector;
}
And, declare the vector in the header and include it in the source file.
Is there a reference covering situations where you must include in the header, and situations where you can pull the includes into the source file?
You cannot safely forward declare STL templates, at least if you want to do it portably and safely. The standard is clear about the minimum requirements for each of the STL element, but leaves room for implemtation extensions that might add extra template parameters as long as those have default values. That is: the standard states that std::vector is a template that takes at least 2 parameters (type and allocator) but can have any number of extra arguments in a standard compliant implementation.
What is the point of not including string and vector headers? Surely whoever is going to use your class must have already included it since it is on your interface.
When you ask about a reference to decide when to include and when to forward declare, my advice would be: include everything that is part of your interface, forward declare internal details.
There are more issues here that plain compilation performance. If you push the include of a type that is in your public (or protected) interface outside of the header you will be creating dependencies on the order of includes. Users must know that they must include string before including your header, so you are giving them one more thing to worry about.
What things should be included in the implementation file: implementation details, loggers, elements that don't affect the interface (the database connectors, file headers), internal implementation details (i.e. using STL algorithms for your implementation does not affect your interface, functors that are created for a simple purpose, utilities...)
With a very few exceptions, you are not allowed to add things to the std:; namespace. For classes like vector and string, you therefore have no option but to #include the relevant Standard header files.
Also, notice that string is not a class, but a typedef for basic_string<char>.
This won't help for vector or string, but it might be worth mentioning that there is a forward reference header for iostream, called iosfwd.
Standard containers often have additional default template parameters (allocators, etc.) so this will not work. For example, here's a snippet from GNU implementation:
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{ ... };
This was something I was trying to do earlier too, but this is not possible due to templates.
Please see my question: Forward Declaration of a Base Class
As such headers don't change during your development it's not worth optimizing that anyway...
There is no simple obvious way to do it (as others have explained it very well).
However these headers should be seen as being part of the language (really!), so you can let them in your own headers without any problem, nobody will ever complain.
If your concern is compilation speed, I encourage you to use pre-compiled header instead and put these std headers in it (among other things). It will significantly increase your compilation speed.
Sorry the for the "real winner is the one who avoid the fight" kind of answer.
Just include the header in any file where you reference an STL collection.
As others have mentioned, there's not a way to reliably forward declare the STL classes, and even if you find one for your particular implementation, it will probably break if you use a different STL implementation.
If the compilation units don't instantiate the classes, it won't make your object files any bigger.
If string and vector are used only in signatures of non-public members of you class, you could use the PImpl idiom:
// MyClass.h
class MyClassImpl;
class MyClass{
public:
MyClass();
void MyMethod();
private:
MyClassImpl* m_impl;
};
// MyClassImpl.h
#include <vector>
#include <string>
#include <MyClass.h>
class MyClassImpl{
public:
MyClassImpl();
void MyMethod();
protected:
std::vector<std::string> StdMethod();
};
// MyClass.cpp
#include <MyClass.h>
#include <MyClassImpl.h>
void MyClass::MyMethod(){
m_impl->MyMethod();
}
You are always including vector and string in the header file, but only in the implementation part of your class; files including only MyClass.h will not be pulling in string and vector.
WARNING
Expect that doing this will cause uproar.
The language allows you to derive your own classes:
// MyKludges.h
#include <vector>
#include <string>
class KludgeIntVector : public std::vector<int> {
// ...
};
class KludgeDoubleVector : public std::vector<double> {
// ...
};
class KludgeString : public std::string {
// ...
};
Change your functions to return KludgeString and KludgeIntVector. Since these are no longer templates, you can forward declare them in your header files, and include MyKludges.h in your implementation files.
Strictly speaking, derived classes do not inherit base class constructors, destructors, assignment operators, and friends. You will need to provide (trivial) implementations of any that you're using.
// LotsOfFunctions.h
// Look, no includes! All forward declared!
class KludgeString;
// 10,000 functions that use neither strings nor vectors
// ...
void someFunction(KludgeString &);
// ...
// Another 10,000 functions that use neither strings nor vectors
// someFunction.cpp
// Implement someFunction in its own compilation unit
// <string> and <vector> arrive on the next line
#include "MyKludges.h"
#include "LotsOfFunctions.h"
void someFunction(KludgeString &k) { k.clear(); }
Maybe you would better use the pimpl idiom: it appears to me that you don't want to expose the implementation of your class to client code. If the vector and string objects are aggregated by value, the compiler needs to see their full declarations.
With the exception of adding overloads to std::swap (the only exception I can think of right now), you are generally not allowed to add anything to the std namespace. Even if it were allowed, the actual declaration for std::vector is a lot more complicated than the code in the OP. See Nikolai N Fetissov's answer for an example.
All that aside, you have the additional problem of what your class users are going to do with functions that return a std::vector or std::string. The C++ Standard section 3.10 says that functions returning such objects are returning rvalues, and rvalues must be of a complete type. In English, if your users want to do anything with those functions, they'll have to #include <vector> or <string> anyway. I think it would be easier to #include the headers for them in your .h file and be done with it.
I assume your objective here is to speed up compile times? Otherwise I'm not sure why you would want to remove them.
Another approach (not pretty but practical) is to use macro guards around the include itself.
e.g.
#ifndef STDLIB_STRING
#include <string>
#define STDLIB_STRING
#endif
Although this looks messy, on large codebases it does indeed increase the compile times. What we did is create a Visual Studio macro that will automatically generate the guards. We bind the macro to a key for easy coding. Then it just becomes a company coding standard (or habit).
We also do it for our own includes as well.
e.g.
#ifndef UTILITY_DATE_TIME_H
#include "Utility/DateTime.h"
#endif
Since we have Visual Studio helpers to auto-generate the guards when we create our own header files, we don't need the #define. The macro knows it's a internal include because we always use the
#include ""
format for our own includes and
#include <>
for external includes.
I know it doesn't look pretty but it did speed up our compile times on a largish codebase by over 1/2 hour (from memory).