我正在使用Reactor模式编写基于小型C ++消息的通信框架。我遇到的问题是应用程序(用户定义的)消息的序列化。为了防止API出现重复信息,我假设序列化函数。有一个Archive类,它保存了消息的序列化形式,但它是模板,因此用户可以选择其二进制形式。假设每个消息只有一个序列化函数可用(已定义),因此二进制类型的类型推导可以从函数签名中清晰地推导出来。我们来看看代码:
template <typename T> struct Archive {
T t;
}; // struct Archive
template <typename Message, typename T>
void serialize(const Message& msg, Archive<T>* const ar);
struct Signal {
void* payload;
};
template <typename T> struct Wrapper {
Signal* pack() {
Signal* s = new Signal;
archive(&serialize, &s->payload);
return s;
}
template <typename P>
void archive(void(*f)(const T&, Archive<P>* const), void** payload) {
Archive<P> ar;
f(t, &ar);
P* p = new P;
*p = ar.t;
*payload = p;
}
T t;
};
struct TestMsg {
int i;
};
template <>
void serialize(const TestMsg& msg, Archive<int>* const ar) {
ar->t = msg.i;
}
int main() {
Wrapper<TestMsg> msg;
msg.pack();
return 0;
}
编译器声称它无法推断出P类型。有没有其他方法(没有特征)来帮助编译器进行这样的演绎?
亲切的问候,Gracjan
编辑(14-05-2013 15:42):根据评论中的要求,我附上了Traits解决方案:
/****** Library part *******/
template <typename T> struct Archive {
T t;
}; // struct Archive
template <typename T> struct MessageTrait {};
template <typename Message, typename T>
void serialize(const Message& msg, Archive<T>* const ar);
struct Signal {
void* payload;
};
template <typename T> struct Wrapper {
Signal* pack() {
typedef Archive<typename MessageTrait<T>::ArchType> ArchiveType;
Signal* s = new Signal;
ArchiveType ar;
serialize(t, &ar);
return s;
}
T t;
};
/****** Application part ******/
struct TestMsg {
int i;
};
template<> struct MessageTrait<TestMsg> {
typedef int ArchType;
};
template <>
void serialize(const TestMsg& msg, Archive<int>* const ar) {
ar->t = msg.i;
}
int main() {
Wrapper<TestMsg> msg;
msg.pack();
return 0;
}
答案 0 :(得分:1)
template <typename Message, typename T>
void serialize(const Message& msg, Archive<T>* const ar);
template <typenane T>
Signal* Wrapper<T>::pack() {
Signal* s = new Signal;
archive(&serialize, &s->payload);
return s;
}
在上面的代码中,serialize
是模板的名称,用于代替函数,它表示模板的所有可能的特化(即模板的每个可能的替换)产生的完整的重载集参数)。同时archive
是一个模板,可以从子集中获取符合最小限制的任何函数,第二个参数是Archive
模板的实例化。
这里的问题不是模板不能推断出参数,而是有无限类型符合要求,你的问题太开放了。这带来了下一个问题,一切都需要成为一个模板吗?
一般来说,专门化函数模板是一个坏主意,serialize
模板真的可能是一个过载吗?您是否可以将问题的一般性降低到 deducible与否只有一两个候选人的情况?我觉得你正在向自己开放你可能或不需要的太多自由度,然后通过任何可以匹配的事实得到一点点。