函数模板参数推导
Function template parameter deduction
我正在使用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类型。有没有其他的方法(没有特征)来帮助编译器这样的演绎?
敬礼,格拉詹
编辑(14-05-2013 15:42):根据评论中的要求,我附上了性状解决方案:
/****** 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;
}
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
模板真的是一个过载吗?你能否将问题的通用性简化到可演绎或不可演绎只有一个或两个候选者?我有一种感觉,你把自己开放给了太多你可能需要或不需要的自由,然后被任何都可以匹配的事实所束缚。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 具有常量引用参数的函数模板专用化
- 使用可变参数函数作为模板参数
- std::span<const T> 作为函数模板中的参数
- 如何在C++中伪造虚拟可变参数函数模板?
- C++ std::functional 中的可变参数函数模板
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 三个参数函数模板令人困惑的示例
- 父可变参数函数模板专门用于子级
- C++如何将可变参数函数模板的参数包 -> 包装到 lambda 中
- 将函数传递给可变参数函数模板
- 为什么可变参数函数模板中的这个 constexpr 不是常数?
- 将多个初始值设定项列表传递到可变参数函数模板时遇到问题
- 依赖类型不明确的 c++11 可变参数函数模板重载是否不明确
- 操作可变参数函数模板的函数参数
- C++11 中的非类型可变参数函数模板
- 将可变参数函数模板的每个参数传递给返回void的函数
- 包扩展不在最后一个参数中的可变参数函数模板
- 将可变参数函数模板参数存储到联合向量中的最有效方法
- Clang 和 GCC 在解决可变参数函数模板重载时的行为不同