【问题标题】:Pass a function template to other function将函数模板传递给其他函数
【发布时间】:2012-03-07 16:50:28
【问题描述】:

假设我有一个对任意容器类型 (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 才能使其工作?

编辑:根据 cmets 的要求,这是一个最小的可编译示例...

#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.
}

【问题讨论】:

  • 你缺少最小的可编译示例
  • 为什么要使用函数指针?我相信在这里使用仿函数会更好。
  • @AlexTheo 感谢您的评论。当然,使用函子解决方案很简单! Bob 发布了一个类似的解决方案作为答案。我会去的!

标签: c++ templates function-pointers


【解决方案1】:

在线演示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 );
}

【讨论】:

    【解决方案2】:

    如果您知道 foo 与 int 向量一起使用,则可以传递 bar&lt; std::vector&lt;int&gt; &gt; 函数。

    一个合理的解决方案是定义foo 的模块也为使用的容器定义typedef。那么你甚至不需要bar 作为模板。

    【讨论】:

    • 感谢您的回答。我希望 foo 的调用者不知道 foo 在内部是如何工作的——他只知道他必须传递一个在任意容器上运行的函数。
    • @fdlm 但该函数不能在任意容器上运行。它是一个模板函数,因此可以将其视为在编译时为所需的容器类型创建函数。
    • @juanchopanza 是的,但我不希望 foo 的调用者知道 foo 在内部使用哪个容器。所以模板实例化必须发生在 foo 函数本身中
    • @JurajBlaho:这将是一个合理的解决方案,但我个人更喜欢仿函数解决方案,因为它向 foo 函数的用户暴露了更少的内部结构。
    【解决方案3】:

    这样的? (没有完全清醒,可能会错过重点)

    #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 在 cmets 中指出的那样,使用仿函数可能是这里最简单的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 2017-03-07
    • 1970-01-01
    相关资源
    最近更新 更多