简体   繁体   English

模板和函数对象 - c ++

[英]templates and function objects - c++

i have a problem with this class. 我这堂课有问题。
the goal is to make the main function work properly. 目标是使主要功能正常工作。 we were supposed to implement the "And" function object so that the code will work. 我们应该实现“And”函数对象,以便代码可以工作。 i can't find what is the problem with our solution. 我找不到解决方案的问题。
(the solution start and end are marked in comments in the code before the "main" function) (解决方案的开始和结束在“main”函数之前的代码中的注释中标记)
can you please help? 你能帮忙吗?
thanks 谢谢

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

Obviously, you don't know the T parameter when creating your functor. 显然,在创建仿函数时,您不知道T参数。 Did you consider delaying the introduction of T to the actual call (ie. making operator() a member-template)? 您是否考虑将T的引入延迟到实际调用(即使operator()成为成员模板)?

your not calling your overloaded () operator when you create the object here: return AndFunction<Function1, Function2, T>(f1, f2); 你在这里创建对象时不要调用你的overloaded ()运算符: return AndFunction<Function1, Function2, T>(f1, f2); (you need a () before the ; ) this code shouldn't even compile, actually, as currently it returns an object, not a bool. (你需要一个()之前的; )这个代码甚至不应该编译,实际上,因为它当前返回一个对象,而不是一个bool。


EDIT: As pointed out, the function ( bool And(Function1 f1, Function2 f2) ) must not return bool but rather a functional object for count_if to call via the overloaded () operator 编辑:正如所指出的,函数( bool And(Function1 f1, Function2 f2) )不能返回bool ,而是count_if的函数对象通过overloaded ()运算符调用

Technically speaking you should be using the unary_function and binary_function classes as parents if you'd like them to place nice with STL algorithms. 从技术上讲,如果您希望将它们与STL算法放在一起,那么您应该使用unary_functionbinary_function类作为父类。 Here: 这里:

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

In your case you need to do 在你的情况下,你需要做

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

so that you don't confuse the operator with object creation and that you specify how you are to receive the function instructions. 这样您就不会将操作符与对象创建混淆,并且您指定了接收函数指令的方式。

On the flip side, the way your main works I think you really just want 另一方面,你认为你真正想要的main方式

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

Hope that helps. 希望有所帮助。

The template parameter T can't be inferred, it must be specified explicitly: 无法推断模板参数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's solution is better and works as follows: 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 ******

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM