Reputation: 13
I'm trying to forward declare the header files #include<memory_resource>
and #include<deque>
. But the following doesn't seem to work. This is pseudo-code:
A.hpp
class memory_resource;
class deque;
class A
{
public:
...
private:
std::pmr::deque<index_t> tempQueue;
}
A.cpp
#include<memory_resource>
#include<deque>
...
Upvotes: 1
Views: 825
Reputation: 6637
For a rule of thumb, you should not forward declare anything from the standard library, unless the class specifically says it can be forward declared.
To use anything from the standard library, you must actually include them:
// A.hpp
#include <memory_resource>
#include <deque>
class A {
std::pmr::deque<index_t> tempQueue;
}
Now, let's pretend you are not forward declaring anything from the standard library. You don't forward declare header files, instead you forward declare classes.
So if you have a class named deque
defined in my_deque.cpp
file, in another file, you might do:
// my_deque.cpp
class deque { /* some definitions ... */ };
// A.hpp
class deque;
You don't forward declare the file, my_deque
, instead you forward declare the class deque
.
Secondly, the deque
class was actually located in a namespace. So in order to forward declare deque
in another file, you must declare it within the same namespace:
// my_deque.cpp
namespace my_std::pmr{
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
class deque;
}
Third, deque
was actually a templated class, so to forward declare it, you must also declare it along all the template argument, including anything with default arguments:
// my_deque.cpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque;
}
Fourth, you cannot use a forward declared class as a class member directly. In order to create a class, you must be able to calculate the size of the class. To do that, you must also know the sizes of each class members. However, you can't know the size of a forward declared class, because you don't know what members does that class have, so you can't use a forward declared class as a class member.
However, you can use a pointer of a forward declared class as a class member, since all pointers have the same size:
// my_deque.cpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque;
}
class A{
my_std::pmr::deque<index_t>* p_tempQueue;
}
Upvotes: 1
Reputation: 238301
No, you cannot "forward declare header files".
In order to define a member of a given type, that type must first be defined. You can achieve that by including the header that defines it.
Since you define the class A
in A.hpp and that class has a member of type std::pmr::deque<index_t>
, you must include the definition of std::pmr::deque
into A.hpp, before the definition of the class A
.
Here is a working example:
// A.hpp
#include <deque>
#include <memory_resource>
using index_t = int;
class A
{
std::pmr::deque<index_t> tempQueue;
};
Upvotes: 3