【问题标题】:Passing parameter to function as argument of another function将参数作为另一个函数的参数传递给函数
【发布时间】:2017-08-07 14:43:07
【问题描述】:

我处于这种情况:

template<class  T>
void testFuncMulti (set<T> setInput,  bool (*f)() ) { 
  f();
}

 bool func()
{
    cout   << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testSet; 
        testSet.insert("XXX");
     testFuncMulti(testSet,  &func); 
    return 0;
} 

我想要实现的是将参数传递给最后一个函数“func”。

尝试了许多不同的方法,但仍然没有。

这是我的尝试:

template<class  T>
void testFuncMulti (set<T> setInput,  bool (*f)(T) ) { 
  f(T);
}

template<class  T>
 bool func(T val)
{
    cout   << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testSet; 
        testSet.insert("XXX");
     testFuncMulti(testSet,  &func(string("YYY"))); 
    return 0;
} 

对不起,我是 C++ 新手...请帮助!

更新:

解决了!!

#include <iostream>
#include <functional>
#include <set>
 using namespace std;

template<class  T, class U>
void testFuncMulti (const set<T> setInput, U f) { 

     typename set<T>::iterator iter;
                for(iter = setInput.begin();iter != setInput.end();++iter) {
                        f(*iter); 
                }
}

template<class  T>
 bool func(const T val)
{   

    cout <<val  << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testInput; 
        testInput.insert("XXX");
         testInput.insert("XXX222");
    testFuncMulti(testSet,   func<string> );  
    return 0;
}

【问题讨论】:

  • 也许你可以试试std::function。这也允许其他类型的“功能”。

标签: c++


【解决方案1】:

您要实现的目标称为函数绑定。此外,参数应以 C++ 方式编写 - std::function&lt;bool()&gt;。或者,正如 @chris 在 cmets 中提到的,将另一个参数与任何可调用的参数一起使用。

这里可以通过两种方式实现。 STL 一号:

template<class  T, class U>
void testFuncMulti (set<T> setInput, U f) { 
  f();
}

template<class  T>
 bool func(T val)
{
    cout   << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testSet; 
        testSet.insert("XXX");
     testFuncMulti(testSet,  std::bind(func<int>, string("YYY"))); 
    return 0;
} 

或使用 lambda:

template<class  T, class U>
void testFuncMulti (set<T> setInput, U f) { 
  f();
}

template<class  T>
 bool func(T val)
{
    cout   << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testSet; 
        testSet.insert("XXX");
     testFuncMulti(testSet, []() { return func("YYY"); }); 
    return 0;
} 

但是,它可能对您不是很有用 - 我假设您也想向函数传递一些东西。

在这种情况下,绑定可以是部分的。此外,您可能希望通过引用传递对象。

template<class  T, class U>
void testFuncMulti (const set<T>& setInput, U f) { 
  f(*setInput.begin());
}

template<class  T>
 bool func(const T& val, const T& second)
{
    cout   << "Hello!" <<  endl;  
    return true;
}

int main() { 
    set<string> testSet; 
        testSet.insert("XXX");
     testFuncMulti(testSet,  std::bind(func<int>, string("YYY"))); 
    return 0;
}

【讨论】:

  • 你的第二个例子忘了返回一些东西。
  • std::function 对此太过分了。 testFuncMulti 已经是一个模板,只需将模板参数设为任何可调用对象,而不是将其类型擦除为 std::function。 Lambda 几乎总是比std::bind 更好用,这来自于实际编写std::bind 实现的人。
  • @chris,我同意(并且我已经更新了问题),但是,对于 C++ 的新手,我发现 std::function 的方法更容易解释。
  • @chris 您是否有标准库实现的std::bind 首选 lambda 的实现者的链接/参考?我想阅读更多:我实际上更喜欢使用std::bind,因为它的使用很简单,而且我对其他观点非常感兴趣。
  • @Mark, #include &lt;functional&gt;.
【解决方案2】:

将函数指针作为参数传递时,与调用函数指针时不同:

因此,需要将参数保存在某处并通过调用检索。通过引用(因此值可以在两者之间更改)或通过值(因此注册函数的时刻定义参数的值)。

在这两种情况下,似乎 lambdas/functors 是最合适的解决方案:

#include <iostream>
#include <functional>
#include <set>

template<class  T>
void testFuncMulti (std::set<T> setInput,  std::function<bool()> f ) { 
  f();
}

int main() { 
    std::set<std::string> testSet; 
        testSet.insert("XXX");
    int value = 42; // I like this number
    auto func = [&value]()->bool
    {
        std::cout << "Hello world! " << value << std::endl;
        return true;
    };
    testFuncMulti(testSet,  func); 
    return 0;
} 

.

已编辑:基于 OP 注释,没有 lambda 或函数式的解决方案(应该兼容 C++98):

#include <iostream>
#include <set>

template<class  T, class U>
void testFuncMulti (std::set<T> setInput,  U f ) {
  f();
}

struct Functor
{
    int value;
    bool operator()()
    {
        std::cout << "Hello world! " << value << std::endl;
        return true;
    }
};

int main() {
    std::set<std::string> testSet;
        testSet.insert("XXX");

    Functor func;
    func.value = 42; // I like this number
    testFuncMulti(testSet,  func);
    return 0;
}

【讨论】:

  • 这适用于大肠杆菌。你可以详细说明 gcc 4.3.6 没有 lambdas 吗?
  • @Mark:我找不到测试 Gcc 4.3.6 的页面,但我添加了带有仿函数的解决方案,它应该在 C++98 下工作
猜你喜欢
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-09
  • 2021-04-21
  • 1970-01-01
相关资源
最近更新 更多