2010-07-22 6 views
3

이 클래스에 문제가 있습니다.
목표는 주 기능을 올바르게 작동시키는 것입니다. 우리는 코드가 작동 할 수 있도록 "And"함수 객체를 구현하기로되어있었습니다. 나는 우리 솔루션의 문제점을 발견 할 수 없다.
(솔루션 시작과 끝은 코드에서 "main"함수 앞에 주석으로 표시되어 있습니다)
도와 주시겠습니까? 당신의 펑터를 만들 때
감사템플릿 및 함수 개체 - 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

정확히 작동하지 않는 기능은 무엇입니까? 내가 이상한 점은 연산자 bool에서 함수를 전달한다는 것입니다. – codymanix

+0

몇 가지주의 사항 : 1. Functors는 보통'std :: unary_function'과'std :: binary_function'을 상속 받거나'first_argument_type','second_argument_type','result_type' typedef를 정의합니다. 기능. 2. 반복자 이외의 클래스 객체는 보통 const 참조에 의해 전달됩니다. 3.'operator()'는 보통 const입니다. 4. 문자 리터럴은 상수 객체이며, char * 로의 변환은 권장하지 않습니다. 5. 펑터 'NotNull','BeginsWith' 및 DivideBy는 일반적인 것일 수 있습니다. – Philipp

답변

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의 솔루션은 더 나은 및 작동합니다 : 명시 적으로 지정해야합니다

,536,913,632 10
//***** 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의 도입을 지연하는 것을 고려 했습니까 (즉, operator()을 회원 템플릿으로 지정)?

2

당신의 당신이 여기에 객체를 생성 할 때 오버로드 () 연산자를 호출하지 : return AndFunction<Function1, Function2, T>(f1, f2);,이 코드도 실제로 컴파일 안 (당신은 ; 전에 () 필요)와 같은 현재는 객체가 아닌 부울을 반환합니다.


EDIT : 지적한 바와 같이, 함수 (bool And(Function1 f1, Function2 f2) )의 bool을 돌려주지해야 오히려 count_if하는 기능 개체가 과부하 () 연산자

+0

실제로'bool'이 아니라 함수 객체를 반환한다고 가정합니다. – jpalecek

+0

예, 그냥'bool And (Function1 f1, Function2 f2)'정의를 진행 했으므로 버그가 반전 된 것 같습니다 (버그를 실제로 반전시킬 수 있다면? : P) – Necrolis

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; 
    } 
}; 

희망합니다.