从转发声明的 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 ....
};
B
有 MyArray<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 ...
};
Manager
是 B
的经理并做其他事情。
#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`.
是否有可能获得 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 ....
};
B
有 MyArray<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 ...
};
Manager
是 B
的经理并做其他事情。
#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`.