Is it possible to get return type UglyIterator<>
of a function of a class B::f
which is forward declaration?
MyArray
is a class that acts like std::vector
.
Its begin()
and end()
function return a ugly type.
template<class T> class MyArray{
UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra> begin(){
//some code
}
//... other functions ....
};
B
has MyArray<int>
as a value field.
With the magic of auto-keyword, B
can pretend to be a neat class.
#include "MyArray.h"
class B{ //just a bundle of data
MyArray<int> bField;
public: auto f(){ //<--- neat
return bField.begin();
}
//... other fields ...
};
Manager
is a manager of B
and do other things.
#include "B.h"
class Manager{ //just a bundle of data
decltype(&B::f) mField; //I can cache it, so neat!
//^ actually it is "UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra>"
//... other functions/fields ...
};
As project grow, I noticed that Manager.h
was included in many files, and MyArray
's code changed very often.
To reduce compile time, I decided to forward declaration at Manager
.
I changed mField
to mFieldPtr
, but I get compile error :-
class B;
class Manager{
std::unique_ptr<std::result_of<decltype(&B::f)>::type> mFieldPtr;
//^ should compile error (can not recognize "B::f")
//... other functions ...
};
How to get the return type decltype(&B::f)
elegantly?
Create a new file B_TopHeader.h
.
using B_F_returnType = UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra>;
//^ the type "UglyIterator" also need another forward declaration
Then let the Manager
#include
B_TopHeader.h
instead :-
#include "B_TopHeader.h"
class Manager{
std::unique_ptr< B_F_returnType > mFieldPtr;
//... other functions ...
};
However, I think it is not elegant. It seems to be a hack.
I have to forward the return type manually.
You may use Pimpl idiom to hide the dependency, something like:
class Manager
{
public:
~Manager() noexcept; // you certainly have also to handle copy/move
// Stuff using mFieldPtr, but which doesn't return it.
private:
std::unique_ptr<struct Impl> mImpl;
};
And in cpp
#include "Manager.h"
#include "B.h"
struct Manager::Impl
{
// Implementation using mField
decltype(&B::f) mField;
};
Manager::~Manager() noexcept = default;
// Forward methods of `Manager` to `Impl`.