2010-07-22 35 views
3

我有這個類的問題。
目標是使主要功能正常工作。我們應該實現「And」函數對象,以便代碼可以工作。我無法找到解決方案的問題。
(解決方案的開始和結束在「主」功能之前的代碼註釋中標註)
你能幫忙嗎?
感謝模板和函數對象 - C++

#include <iostream> 
#include <algorithm> 

using namespace std; 

class NotNull 
{ 
    public: 
    bool operator()(const char* str) {return str != NULL;} 
}; 

class BeginsWith 
{ 
    char c; 
    public: 
    BeginsWith(char c) : c(c) {} 
    bool operator()(const char* str) {return str[0] == c;} 
}; 

class DividesBy { 
    int mod; 
    public: 
    DividesBy(int mod) : mod(mod) {} 
    bool operator()(int n) {return n%mod == 0;} 
}; 

//***** This is where my sulotion starts ****** 

template <typename Function1, typename Function2, typename T> 
class AndFunction 
{ 
    Function1 f1; 
    Function2 f2; 
    public: 
    AndFunction(Function1 g1, Function2 g2) : f1(g1), f2(g2) {} 
    bool operator()(T t) 
    { 
     return (f1(t) && f2(t)); 
    } 
}; 

template <typename Function1, typename Function2, typename T> 
AndFunction <Function1, Function2, T> 

bool And(Function1 f1, Function2 f2) 
{ 
    return AndFunction<Function1, Function2, T>(f1, f2); 
} 

//***** This is where my sulotion ends ****** 

int main(int argc, char** argv) 
{ 
    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    char* strings[4] = {"aba", NULL, "air", "boom"}; 
    cout << count_if(array,array+10,And(DividesBy(2),DividesBy(4))) << endl; 
    // prints 2, since 4 and 8 are the only numbers which can be divided by 
    // both 2 and 4. 
    cout << count_if(strings,strings+4,And(NotNull(),BeginsWith('a'))) <<endl; 
    // prints 2, since only "aba" and "air" are both not NULL and begin 
    // with the character 'a'. 
    return 0; 
} 
+0

什麼不工作?我覺得奇怪的是,你在運算符布爾中將t傳遞給你的函數。 – codymanix 2010-07-22 11:25:53

+0

一些注意事項:1.函數通常從'std :: unary_function'和'std :: binary_function'繼承,或者定義typedef'first_argument_type','second_argument_type','result_type'以使它們與例如。 Boost.Functions。 2.迭代器以外的類對象通常由const引用傳遞。 3. operator()通常是const。 4.字符文字是常量對象,並且不鼓勵將它們轉換爲'char *'。 5.函子'NotNull','BeginsWith'和'DividesBy'也可以是通用的。 – Philipp 2010-07-22 11:38:22

回答

0

模板參數T無法推斷打電話,它必須明確指定:

template <typename T, typename Function1, typename Function2> 
AndFunction <Function1, Function2, T> 
And(Function1 f1, Function2 f2) 
{ 
    return AndFunction<Function1, Function2, T>(f1, f2); 
} 

//***** This is where my sulotion ends ****** 

int main(int argc, char** argv) 
{ 
    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    char* strings[4] = {"aba", NULL, "air", "boom"}; 
    cout << count_if(array,array+10,And<int>(DividesBy(2),DividesBy(4))) << endl; 
    // prints 2, since 4 and 8 are the only numbers which can be divided by 
    // both 2 and 4. 
    cout << count_if(strings,strings+4,And<const char*>(NotNull(),BeginsWith('a'))) <<endl; 
    // prints 2, since only "aba" and "air" are both not NULL and begin 
    // with the character 'a'. 
    return 0; 
} 

jpalecek的解決方案是更好的工作原理如下:

//***** This is where my sulotion starts ****** 

template <typename Function1, typename Function2> 
class AndFunction 
{ 
    Function1 f1; 
    Function2 f2; 
    public: 
    AndFunction(Function1 g1, Function2 g2) : f1(g1), f2(g2) {} 
    template<typename T> bool operator()(T) 
    { 
     return (f1(t) && f2(t)); 
    } 
}; 

template <typename Function1, typename Function2> 
AndFunction <Function1, Function2> 
And(Function1 f1, Function2 f2) 
{ 
    return AndFunction<Function1, Function2>(f1, f2); 
} 

//***** This is where my sulotion ends ****** 
3

很顯然,你沒有創建仿函數時知道T參數。您是否考慮延遲將T引入實際呼叫(即,使01​​成爲成員模板)?

2

您,當您在這裏創建對象沒有要求你重載()運營商: return AndFunction<Function1, Function2, T>(f1, f2);(你;之前需要一個())這個代碼不應該甚至編譯,實際上,因爲目前它返回一個對象,而不是一個布爾值。


編輯:由於所指出的,功能(bool And(Function1 f1, Function2 f2) )不能返回bool而是用於count_if功能對象經由重載()操作者

+0

實際上它不應該返回'bool',而是函數對象。 – jpalecek 2010-07-22 11:37:49

+0

是的,我只是定義'bool和(Function1 f1,Function2 f2)',所以猜測錯誤是反轉的(如果一個可以真正反轉錯誤?:P) – Necrolis 2010-07-22 12:05:15

1

從技術上講,如果您希望他們使用STL算法,您應該使用unary_functionbinary_function類作爲父項。在這裏:

template<typename Func1, typename Func2,typename T> 
struct AndFunction : public unary_function<T,bool>{ 
    AndFunction(Func1 _func1, Func2 _func2) 
     : _myFunc1(_func1), 
     _myFunc2(_func2){} 

    bool operator()(T _t){ 
     return _myFunc1(_t) && _myFunc2(_2); 
    } 

private: 
    Func1 _myFunc1; 
    Func2 _myFunc2; 
}; 

你的情況,你需要做的

template<typename Func1, typename Func2, typename T> 
AndFunction<Func1, Func2, T> And(Func1 _func1, Func2 _func2){ 
    return AndFunction<Func1,Func2,T>(_func1,_func2); 
}; 

,讓你不要混淆對象的創建操作員和指定你是如何接收功能的指令。

在另一面,你main作品我覺得你的方式真的只是想

struct And : public binary_function<bool, bool, bool>{ 
    bool operator()(bool _1, bool _2){ 
     return _1 && _2; 
    } 
}; 

希望有所幫助。