2014-01-13 125 views
1

我想在名爲Map的類中創建MapIf函數。 MapIf將被稱爲像這樣:函數獲取函數指針和類指針?

void addThree(int& n) { 
    n += 3; 
} 

class startsWith { 
    char val; 

public: 

    startsWith(char v) : val(v) {}; 

    bool operator()(const std::string& str) { 
     return str.length() && char(str[0]) == val; 
    } 
}; 

int main(){ 
... 
    startsWith startWithB('B'); 

    Map<std::string, int> msi; 

    MapIf(msi, startWithB, addThree); 
    return 0; 
} 

會是什麼MapIf的聲明?

void MapIf(const Map& map, class condition, void (*function)(ValueType)); 

可以嗎?

+0

我不知道你是怎麼知道函數調用看起來像什麼,但不知道函數原型的。 –

+0

映射爲std :: map(關聯容器)還是map-reduce? (對序列中的每個元素執行操作)。 可能在這裏,因爲你正在尋找一個關鍵字是否有一個謂詞,然後對它的值進行操作。 – CashCow

回答

1

以下應符合您的原型。

template <typename Key, typename Value, typename Condition> 
void MapIf(const Map<Key, Value>& map, Condition condition, void (*function)(Value&)); 
+0

是的,如果有疑問,只需模板所有參數,並讓編譯器計算出您實際需要的內容... 在條件的情況下,儘管我同意必須是模板參數。 – CashCow

+0

你爲什麼要模仿每個參數?那很容易出現尷尬的錯誤;例如該函數可以用任何東西來調用,但是當函數體被編譯時,你最終會得到神祕的錯誤消息。 –

+0

@ PeterR.Bloomfield:OP沒有提供'Map','ValueType'。所以我沒有使用魔法球,而是提供了一個正確的(模糊的)答案。不,我們有更多的信息,我限制了我的原型。 – Jarod42

0

而是

void MapIf(const Map& map, startsWith condition, void (*addThree)(int)); 
+0

MapIf is genery – user3036061

+2

命名函數指針'addThree'令人困惑。 「MapIf」函數可能可以與任何匹配正確簽名的函數指針一起使用(即,不僅僅是問題中的「addThree」示例)。 –

0

它看起來像你想有多個條件和所有條件是function objects。 我可以建議你使用std :: function作爲條件。在這種情況下,你可以使用這個類和其他類和其他函數,甚至lambda表達式;

MapIf(Map<std::string, int>& map, std::function<bool(const std::string&)> condition, std::function<void(int&)> callback); 

在這種情況下,你可以調用這個函數在此方面:

MapIf(msi, startWithB, addThree); 

MapIf(msi, [](const string& str)->bool{return str.length() % 2 = 0}, addThree); 

MapIf(msi, startWithA, [](int& val){val-=2}); 

你可以使用模板,使其更通用的課程。

+0

爲什麼你會在這裏接受一個'std :: function'對象?通過模板接受一個Functor。 std :: function的目的不是爲了使函數指針聲明易於閱讀,而是爲可調用對象提供類型擦除。幾乎沒有必要將此公開給調用者。 – pmr