2012-07-25 176 views
0

我想从基础知识中学习C++,并且我正在玩弄函数指针。考虑到这一代码:太多的参数,函数指针中的参数太少

#include <iostream> 
#include <string> 
#include <vector> 

bool print(std::string); 
bool print(std::string a) 
{ 
    std::cout << a << std::endl; 
    return true; 
} 

bool call_user_function(bool(std::string), std::vector<std::string>); 
bool call_user_function(bool(*p)(std::string), std::vector<std::string> args) { 
    if (args.size() == 0) 
     return (*p)();     (*) 
    else if (args.size() == 1) 
     return (*p)(args[0]); 
    else if (args.size() == 2) 
     return (*p)(args[0], args[1]); (**) 
} 

int main(int argc, char** argv) 
{ 
    std::vector<std::string> a; 
    a[0] = "test"; 
    call_user_function(print, a); 
    // ok 
    return 0; 
} 

它给我:

main.cpp:28 (*): error: too few arguments to function

main.cpp:32 (**): error: too many arguments to function

我在做什么错?

+0

'a [0] =“test”'是错误的,因为该向量不包含任何元素。如果它至少包含一个,那将起作用。 – GManNickG 2012-07-25 23:13:29

+0

虽然不相关,但紧接在定义之前的函数声明什么也不做。 – 2012-07-25 23:13:57

+0

@GManNickG,哦,我应该使用'push_back()'? – Shoe 2012-07-25 23:16:19

回答

3

p的类型为bool(*)(std::string)。这意味着它是一个指向具有std::string类型的单个参数并返回bool的函数的指针。

p可以指向print,由于print匹配的类型的:它是具有std::string类型的单个参数,并且返回一个bool的功能。

您的第一个错误表达式(*p)()尝试调用p而没有参数。您的第二个错误表达式(*p)(args[0], args[1])尝试使用两个参数调用p

参数个数必须与参数个数相匹配,所以这两个参数都是格式不对的,就像试图直接调用print而没有参数或两个参数会导致编译错误一样。

+0

哦对。傻我。有没有办法做到这一点,它是一个指针,返回一个布尔,但可以有多个参数? – Shoe 2012-07-25 23:13:08

+0

这取决于你想要做什么:'print'只接受一个参数。 “打印”多个参数意味着什么;你期望的行为是什么?一种选择是将'call_user_function'_apply_用于每个参数的用户函数:为每个单独的参数调用一次用户函数。 – 2012-07-25 23:16:10

+0

我想模拟'call_user_function'的PHP行为,它可以调用任何函数并将任何参数传递给它。所以我希望能够创建我的'call_user_function()',它可以调用任何返回一个bool并具有'std :: string'作为参数的函数(并且可以通过vector传递它们)。 – Shoe 2012-07-25 23:18:25

0

print对于没有参数的调用没有重载。

print对于两个std::string参数也没有过载。

+0

Nooo,太晚了:) – Aesthete 2012-07-25 23:13:32

1

@JamesMcNellis已经解决了代码问题。

为了使这样的工作,你可能想要做的事,如:

bool call_user_function(bool(*p)(std::string), std::vector<std::string> args) { 
    bool ret = true; 
    for (int i=0; i<args.size(); i++) 
     ret &= p(args[i]); 
    return ret; 
} 

...或者,你可以使用std :: for_each的(既然你不使用它,无论如何,我“会暂时忽略返回值):

// avoid copying vector by passing reference to const vector. 
void call_user_function(bool (*p)(std::string), std::vector<std::string> const &args) { 
    std::for_each(args.begin(), args.end(), p); 
} 

...但是,既然你刚刚印刷出来的向量的内容,你应该使用什么更多的东西是这样的:

std::copy(a.begin(), a.end(), 
      std::ostream_iterator<std::string>(std::cout, "\n")); 

另请注意,您的a[0] = "test";无效。您需要改为。