我一直在寻找与我的问题有关的例子,但我仍然无法找到解决方案。我发现的最接近的是
Template function as a template argument
我会尝试发布一个工作示例,以防需要它,但到目前为止,我的部分代码涉及到 以下内容:
template<class InterfaceType, class T>
inline void write_info(InterfaceType& interface, T& t) {
InterfaceType::write_info(interface, t);
}
template<class InterfaceType, class T>
inline void write_data(InterfaceType& interface, T& t) {
InterfaceType::write_data(interface, t);
}
template<class InterfaceType, class T>
inline void write_definition(InterfaceType& interface, T& t) {
InterfaceType::write_definition(interface, t);
}
请注意,模板write_info
依赖于具有名为write_info
的方法的接口类型(静态方法)。之所以这样做是因为write_info
函数可以
稍后专门针对特定数据类型而不必重新定义InterfaceType
上的任何内容。
简单的问题是:我们可以使用将函数命名为函数参数的模板来减少上述代码吗?请记住,我真的希望这是可能的,以便我可以避免为专门的数据类型定义所有这3个函数,即
假设foo
是具有两个属性int a
和double b
的结构。然后我可以像这样专门化上述功能:
template<class InterfaceType>
inline void write_info(InterfaceType& interface, foo& t) {
InterfaceType::write_info(interface, t.a);
InterfaceType::write_info(interface, t.b);
}
template<class InterfaceType>
inline void write_data(InterfaceType& interface, foo& t) {
InterfaceType::write_data(interface, t.a);
InterfaceType::write_data(interface, t.b);
}
template<class InterfaceType>
inline void write_definition(InterfaceType& interface, foo& t) {
InterfaceType::write_definition(interface, t.a);
InterfaceType::write_definition(interface, t.b);
}
正如您所看到的,我一遍又一遍地编写相同的代码。在这里,我假设InterfaceType已经为write_info
和write_data
定义了write_definition
,int
和double
。有什么想法吗?
答案 0 :(得分:5)
转换逻辑:而不是为每种类型编写专门的write_thing
重载,编写一个apply
函数,将任意函数应用于每种类型的对象,然后每个类型都有一个重载只需委托write_thing
:
apply
// Define a catch-all apply that handles "everything else"
template <typename Interface, typename Function, typename Object>
void apply(Interface& i, Function f, Object& x) {
f(i, x);
}
// Define overloads for "apply" that handle special cases
template <typename Interface, typename Function>
void apply(Interface& i, Function f, foo& x) {
f(i, x.a);
f(i, x.b);
}
// Define polymorphic adapters for your write_[thing] functions:
struct write_info_impl {
template <typename Interface, typename Object>
void operator()(Interface& i, Object& x) const {
Interface::write_info(i, x);
}
};
// Then implement your write_[thing] functions in terms of the above:
template <typename Interface, typename Object>
void write_info(Interface& interface, Object& x) {
apply(i, write_info_impl(), x);
}