将函数模板传递给其他函数

4
假设我有一个在任意容器类型上执行某些操作的函数(C++11):
template<class containerType>
void bar( containerType& vec ) {

        for (auto i: vec) {
                std::cout << i << ", ";
        }

        std::cout << '\n';
}

我可以像这样从另一个函数中调用此函数:

void foo() {
        std::vector<int> vec = { 1, 2, 3 };
        bar(vec);
}

现在假设我有不同的函数,例如bar,而我想将其中一个函数传递给foo,那么foo看起来会是这样的:

template<class funcType>
void foo( funcType func ) {
    std::vector<int> vec = { 1, 2, 3 };
    func(vec);
}

然而,像这样调用foo:

foo(bar);

无法工作(很明显,因为bar不是函数而是函数模板)。有没有什么好的解决方案?我必须如何定义foo才能使其正常工作?

编辑:以下是一个最小可编译示例,正如评论中要求的那样...

#include <iostream>
#include <vector>
#include <list>

template<class containerType>
void bar( containerType& vec ) {

        for (auto i: vec) {
                std::cout << i << ", ";
        }

        std::cout << '\n';
}

template<typename funcType>
void foo(funcType func) {

        std::vector<int> vals = { 1, 2, 3 };
        func(vals);

}

int main() {
        // foo( bar );  - does not work.
}

你缺少最小可编译示例。 - BЈовић
1
为什么要使用函数指针?我认为在这里使用一个函数对象会更好。 - AlexTheo
@AlexTheo 谢谢您的评论。当然,使用函数对象解决方案就很简单!Bob发布了一个类似的答案。我会采用那个! - fdlm
3个回答

4

在线演示请访问http://ideone.com/HEIAl

这允许您执行foo(bar)。我们不是传递模板函数或模板类,而是传递一个具有模板成员函数的非模板类。

#include <iostream>
#include <vector>
#include <list>

struct {
    template<class containerType>
    void operator() ( containerType& vec ) {

        for (auto i = vec.begin(); i!=vec.end(); ++i) {
                std::cout << *i << ", ";
        }

        std::cout << '\n';

    }
} bar;

template<typename funcType>
void foo(funcType func) {

        std::vector<int> vals = { 1, 2, 3 };
        func(vals);

}

int main() {
        foo( bar );
}

4
如果你知道foo可以使用一个int向量,你就可以传递bar<std::vector<int>>函数。
一个合理的解决方案是为定义foo的模块也定义使用容器的typedef。然后,你甚至不需要bar成为一个模板。

谢谢你的回答。我更希望调用foo的人不知道foo内部是如何工作的 - 他只知道他必须传递一个操作任意容器的函数。 - fdlm
1
@fdlm 但是该函数不适用于任意容器。它是一个模板函数,因此可以将其视为在编译时为所需的容器类型创建函数。 - juanchopanza
@juanchopanza 是的,但我不希望foo的调用者知道foo内部使用哪个容器。因此,模板实例化必须在foo函数本身中进行。 - fdlm
@JurajBlaho:那是一个合理的解决方案,但我个人更喜欢函数对象的解决方案,因为它向foo函数的用户暴露了更少的内部细节。 - fdlm

2

像这样的吗?(我还没完全清醒,可能会错过重点)

#include <iostream>
#include <vector>
#include <list>

struct Test{
template<class containerType>
static void apply( containerType& vec ) {

        for (auto it = vec.begin(); it != vec.end(); ++it) {
                std::cout << *it << ", ";
        }

        std::cout << '\n';
}
};

template<class FuncStruct>
void foo() {

        std::vector<int> vals;
        vals.push_back(1);
        FuncStruct::apply(vals);

}

int _tmain(int argc, _TCHAR* argv[])
{
    foo<Test>();
    return 0;
}

谢谢!正如@AlexTheo在评论中指出的那样,使用函数对象可能是最简单的解决方案。 - fdlm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接