模板函数名称的模板参数

时间:2012-09-26 16:35:58

标签: c++ templates overloading

我一直在寻找与我的问题有关的例子,但我仍然无法找到解决方案。我发现的最接近的是

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 adouble 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_infowrite_data定义了write_definitionintdouble。有什么想法吗?

1 个答案:

答案 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);
}