2012-07-25 174 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";無效。您需要改爲。