【问题标题】:get return type from a function of a class that was forward-ed declaraion从被转发声明的类的函数中获取返回类型
【发布时间】:2017-02-23 08:32:52
【问题描述】:

是否可以获得 UglyIterator<> 类的函数的返回类型 B::f 是前向声明?

示例

MyArray 是一个类似于std::vector 的类。
它的begin()end() 函数返回一个丑陋的类型。

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

B 具有 MyArray&lt;int&gt; 作为 value 字段。
借助自动关键字的魔力,B 可以伪装成一个整洁的班级。

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

如何优雅地获取返回类型decltype(&amp;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 ...
};

但是,我认为它并不优雅。这似乎是一个黑客。
我必须手动转发返回类型。

【问题讨论】:

  • 您可以使用pimpl idiom隐藏Manager的成员。
  • &amp;B::f 的类型不是UglyIterator&lt;…&gt;,而是UglyIterator&lt;...&gt; (B::*)()。你要返回类型还是成员函数指针类型?
  • @kennytm 对不起,我会编辑它。我想要返回类型。谢谢。
  • @Jarod42 非常好的主意.....这可能是一个完美的解决方案...创建一个新类Manager2 那个#include "B.h",并让Manager 存储Manager2*,对?

标签: c++ c++11 forward-declaration decltype pimpl-idiom


【解决方案1】:

你可以使用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`.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 2016-07-01
    相关资源
    最近更新 更多