I want to remove, if possible, the includes of both
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...)
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...
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.
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.
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>
{ ... };
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.