首先,我不确定该如何命名这个问题,所以我希望它足够好。
基本上,我有一大堆具有通用功能的功能,这些功能仅因类型而异。听起来像模板是吗?但这里有一个问题:每个函数都足够具体,我想以不同的方式命名每个函数。
例如,请查看以下代码:
bool GetFriendsList(FriendsListRequestData::CallbackType Callback)
{
check(Callback != nullptr);
FriendsListRequest* Request = new FriendsListRequest(this, GetNewRequestID());
FriendsListRequestData* Data = new FriendsListRequestData(Request, Callback);
return StoreAndPerformRequest(Data);
}
bool GetAccountInfo(AccountInfoRequestData::CallbackType Callback)
{
check(Callback != nullptr);
AccountInfoRequest* Request = new AccountInfoRequest(this, GetNewRequestID());
AccountInfoRequestData* Data = new AccountInfoRequestData(Request, Callback);
return StoreAndPerformRequest(Data);
}
// Many more routines...
这两个功能几乎完全相同。它们的区别仅在于类型和功能名称。我可以模板化这些功能,但它们会有相同的名称。我用宏实现了以下内容,但我不喜欢它会使我的代码难以理解:
#define IMPLEMENT_REQUEST_FUNCTION(Name, RequestType, RequestDataType) \
bool Name(RequestDataType::CallbackType Callback) \
{ \
check(Callback != nullptr); \
RequestType* Request = new RequestType(this, GetNewRequestID()); \
RequestDataType* Data = new RequestDataType(Request, Callback); \
return StoreAndPerformRequest(Data); \
}
class Foo
{
public:
// other stuff...
IMPLEMENT_REQUEST_FUNCTION(GetFriendsList, FriendsListRequest, FriendsListRequestData)
IMPLEMENT_REQUEST_FUNCTION(GetAccountInfo, AccountInfoRequest, AccountInfoRequestData)
// other stuff...
};
我比在类和源中反复添加函数更喜欢宏,但有一种方法可以获得模板化功能,同时命名结果函数所以我不会必须使用宏(或可能使用更友好的宏)?
谢谢。
答案 0 :(得分:1)
怎么样:
template <typename R, typename D>
bool Get(typename D::CallbackType Callback)
{
check(Callback != nullptr);
R* Request = new R(this, GetNewRequestID());
D* Data = new D(Request, Callback);
return StoreAndPerformRequest(Data);
}
inline bool GetFriendsList(FriendsListRequestData::CallbackType Callback)
{
return Get<FriendsListRequest, FriendsListRequestData>(Callback);
}
inline bool GetAccountInfo(AccountInfoRequestData::CallbackType Callback)
{
return Get<AccountInfoRequest, AccountInfoRequestData>(Callback);
}
请注意,您可能还需要对StoreAndPerformRequest()
进行模板化。
答案 1 :(得分:0)
我不知道你的类型等,但这会有效吗?
template<typename Req, typename Data>
bool getGeneric(Data::CallbackType Callback){
if (Callback != nullptr) return false;
Req* request = new T(this, GetNewRequestID()); //what is *this?
Data* data = new Data(request,Callback);
return StoreAndPerformRequest(data);
}
//getGeneric<FriendsListRequest, FriendsListRequestData> == GetFriendsList
//getGeneric<AccountInfoRequest, AccountInfoRequestData> == GetAccountInfo
顺便说一下,模板输入应该能够自动推断出来;我不会认为你必须明确地声明它们,但在某些情况下我之前就错了。
答案 2 :(得分:0)
最简单的方法可能是在每个类中添加data
(或类似的)typedef:
class FriendsListRequestData {};
class FriendsListRequest {
public:
typedef FriendsListRequestData data;
FriendsListRequest(some_class *s, int);
};
class AccountInfoRequestData{};
class AccountInfoRequest {
public:
typedef AccountInfoRequestData data;
AccountInfoRequest(some_class *s, int);
};
然后你可以编写类似的调用代码:
class Foo {
template <class T>
bool Get(typename T::CallbackType t) {
T *Request = new T(this, GetNewRequestID());
typename T::data *Data = new typename T::data(Request, t);
return StoreAndPerformRequest(Data);
}
...你会称之为:
auto bar = Get(some_callback);
auto baz = Get(another_callback);
如果你不能修改这些类,你必须将typedef移到traits类型,并从那里使用它们:
template <class T>
struct req_traits {};
template<>
struct req_traits<FriendsListRequestData> {
typedef FriendsListRequest req;
typedef FriendsListRequestData data;
};
template<>
struct req_traits<AccountInfoRequestData> {
typedef AccountInfoRequest req;
typedef AccountInfoRequestData data;
};
template <class T, class traits=req_traits<T> >
bool Get(typename T::CallbackType t) {
typedef typename traits::req req;
typedef typename traits::data data;
req *Request = new req(this, GetNewRequestID());
data *Data = new data(Request, t);
return StoreAndPerformRequest(Data);
}