从转发声明的 class 的函数中获取 return 类型

get return type from a function of a class that was forward-ed declaraion

是否有可能获得 return 类型 UglyIterator<> 的 class B::f 函数的前向声明?

例子

MyArray 是一个 class,其作用类似于 std::vector
它的begin()end()功能return一个丑陋的类型。

template<class T> class MyArray{
     UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra> begin(){
         //some code
     }
     //... other functions ....
};

BMyArray<int> 作为 字段。
有了auto-keyword的魔力,B可以伪装成整洁的class.

#include "MyArray.h"
class B{  //just a bundle of data
    MyArray<int> bField;
    public: auto f(){  //<--- neat     
        return bField.begin();
    }
    //... other fields  ...
};

ManagerB 的经理并做其他事情。

#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 ...
};

随着项目的发展,我注意到Manager.h被包含在很多文件中,并且MyArray的代码经常更改。

为了减少编译时间,我决定 转发声明Manager
我将 mField 更改为 mFieldPtr,但出现编译错误:-

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 ...
};

如何优雅地得到return类型decltype(&B::f)

我的解决方法

创建一个新文件B_TopHeader.h

using B_F_returnType = UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra>;
//^ the type "UglyIterator" also need another forward declaration    

然后让 Manager #include B_TopHeader.h 代替 :-

#include "B_TopHeader.h"
class Manager{  
    std::unique_ptr< B_F_returnType > mFieldPtr;
    //... other functions ...
};

不过,我觉得不够优雅。好像是hack。
我必须手动 转发 return 类型。

您可以使用 Pimpl idiom 来隐藏依赖关系,例如:

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;
};

并且在 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`.