шаблоны и функциональные объекты - c ++ - PullRequest
3 голосов
/ 22 июля 2010

У меня проблема с этим классом.
цель состоит в том, чтобы основная функция работала должным образом. мы должны были реализовать функциональный объект «И», чтобы код работал. я не могу найти в чем проблема с нашим решением.
(начало и конец решения отмечены в комментариях в коде перед функцией main)
не могли бы вы помочь?
спасибо

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

Ответы [ 4 ]

3 голосов
/ 22 июля 2010

Очевидно, вы не знаете параметр T при создании функтора. Рассматривали ли вы задержку введения T для фактического вызова (т. Е. Превращение operator() в шаблон участника)?

2 голосов
/ 22 июля 2010

вы не вызываете перегруженный оператор () при создании объекта здесь: return AndFunction<Function1, Function2, T>(f1, f2); (вам нужно () перед ;), этот код даже не должен компилироваться, так как в настоящее время он возвращаетобъект, а не bool.


РЕДАКТИРОВАТЬ: Как указано, функция (bool And(Function1 f1, Function2 f2) ) не должна возвращать bool, а скорее функциональный объект для вызова count_if через перегруженный () оператор

1 голос
/ 22 июля 2010

Технически говоря, вы должны использовать классы unary_function и binary_function в качестве родителей, если вы хотите, чтобы они хорошо сочетались с алгоритмами STL.Здесь:

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

Надежда, которая помогает.

0 голосов
/ 22 июля 2010

Параметр шаблона 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 ******
...