12

我有一些功能模板,例如

template <typename T>
void foo(T);

template <typename T>
void bar(T);

// others

我需要将每一个传递给一个算法,该算法将以各种类型调用它,例如

template <typename F>
void some_algorithm(F f)
{
    // call f with argument of type int
    // call f with argument of type SomeClass
    // etc.
}

我不能未经实例化传入我的函数模板,但我也不能用任何特定类型实例化它,因为some_algorithm需要用几种不同类型的参数调用它。

我可以将我的函数模板调整为多态函数对象,例如

struct foo_polymorphic
{
    template <typename T>
    void operator()(T t)
    {
        foo(t);
    }
};

然后将其作为some_algorithm(foo_polymorphic()). 但这需要为我的每个函数模板编写一个单独的适配器。

是否有一种通用方法可以将函数模板调整为多态函数对象,即我可以为需要调整的每个函数模板重复使用某种机制,而不必为每个函数模板单独声明一些东西?

4

2 回答 2

2

该问题的简短版本给出了一个重载名称f,即如何简洁地编写一个ff最终ff(a0, a1, a2, ...)调用的对象f(a0, a1, a2, ...)

多态函子,你如何指出自己,是通常的解决方案。但它必须被定义得不合时宜(因为它有一个模板成员),所以我认为这对于我的回答来说不够简洁。

目前 lambda 表达式产生一个单态函子,所以它们很接近但并不完全在那里。

// set of functions overloaded on int and double
void f(int);
void f(double);

auto ff = [](int i) { return f(i); };

正如 GMan 在评论中指出的那样,多态 lambda 将(应该?)成为简洁地内联编写多态函子的解决方案。

同时,可以编写一个make_overload将多个函子组合为一个的助手,这样

auto ff = make_overload(
    [](int arg0) { return f(arg0); }
    , [](double arg0) { return f(arg0); } );

将“捕获”整个重载集。也许 Boost.Preprocessor 宏可以在这里提供帮助,以便auto ff = POLYMORPHIC_LAMBDA( 1, (int)(double), { return f(arg0); } );内联使用。但是,我怀疑存在数量限制(因此是第一个宏参数),这与通常的离线手写多态函子解决方案不同;所以这对可变参数函数模板没有帮助。

于 2011-08-11T23:12:59.633 回答
1

为什么不能使用模板模板参数?你说你不能在未经实例化的情况下传递你的模板,但我不确定你以前是否听说过这个,告诉我你是否有,它不会工作。

我不知道你的代码结构是什么样的,但你能做类似的事情吗

我知道这行得通,但不知道这是不是你想要的:

template<typename T>
T some_algorithm(T data) { return T(); } // just returning nothing for example

template<typename T, T(*Something)(T)>
class FuncClass {
public:
    T run(T data) { return Something(data); }
};

template<typename T, typename Functor>
void apply_algorithm(T data) {
    Functor F;
    F.run(data);
}

int main() {
    int mydata = 4;
    apply_algorithm<int, FuncClass<int, some_algorithm<int> > >(mydata);

    cin.get();
}
于 2011-08-11T22:41:25.650 回答