如何使函数的返回类型与另一个函数相同?

Ami*_*avi 0 c++ inheritance c++11

我们的研究书中有一个关于对象函数的问题.在c ++中有一个代码,问题是我们要填补空白.代码如下

template <typename Arg, typename Ret> 
class FuncObj {
public:
    typedef Arg argType;
    typedef Ret retType;
    virtual Ret operator()(Arg) = 0;
};

class DivideBy : public FuncObj<int, double> {
protected:
    int divisor;
public:
    DivideBy(int d) {
        this->divisor = d;
    }
    double operator()(int x) {
        return x/((double)divisor);
    }
};

class Truncate : public FuncObj<double, int> {
public:
    int operator()(double x) {
        return (int) x;
    }
};

template < typename Ftype , typename Gtype >
class Compose : public FuncObj <typename Gtype :: argType, typename Ftype :: retType > {
protected:
    Ftype *f; Gtype *g;
public:
    Compose(Ftype f,Gtype g) {
    --------- =f;
    --------- =g; 
    }

    ---------- operator()(____________x) {
        return (_________)((________)(__________)); }
};
Run Code Online (Sandbox Code Playgroud)

理想的结果是

void main() {
    DivideBy *d = new DivideBy(2);
    Truncate *t = new Truncate();
    Compose<DivideBy, Truncate> *c1 = new Compose<DivideBy,Truncate>(d,t);
    Compose<Truncate, DivideBy> *c2 = new Compose<Truncate, DivideBy>(t,d);
    cout << (*c1)(100.7) << endl; // Prints 50.0 
    cout << (*c2)(11) << endl; // Prints 5
}
Run Code Online (Sandbox Code Playgroud)

我真的不知道如何完成这个代码,那么我们应该使用c ++的哪些特性或概念来实现这个功能呢?如果有关于此主题的进一步研究的链接,请写下来.谢谢.

Nel*_*eal 5

这段代码非常糟糕(如果这是材料的平均质量,那么研究书也是如此).

首先,void main()不是有效的签名main.应该是int main()这种情况.其次,如果Compose应该用指针构造,那么它的构造函数应该声明为Compose(Ftype* f, Gtype* g),而不是Compose(Ftype f, Gtype g).第三,代码应包括<iostream>和前缀cout,并endlstd::(或使用using namespace std,但仍然是非常糟糕).最后,所有new应该有一个相应的delete,但更好的是使用智能指针,或根本没有指针.

无论如何,在所有这些之后,填充空白相对简单.
构造函数将按如下方式编写:

Compose(Ftype f,Gtype g) {
    this->f = f;
    this->g = g;
}
Run Code Online (Sandbox Code Playgroud)

...这非常糟糕,因为它强制使用this->不必要的时候(不同地命名参数,或者使用成员初始化列表).
并且调用运算符将​​被写成:

typename Ftype::retType operator()(typename Gtype::argType x) {
    return (*f)((*g)(x));
}
Run Code Online (Sandbox Code Playgroud)

参数类型和返回类型是FuncObj作为模板参数传递给基类的类型,然后调用只是组成fg.

演示.

没有使用任何指针的更好的代码将如下所示:

template<typename Ftype, typename Gtype>
class Compose : public FuncObj<typename Gtype::argType, typename Ftype::retType> {
protected:
    Ftype f;
    Gtype g;
public:
    Compose(Ftype f, Gtype g)
    : f(f), g(g) {
    }

    typename Ftype::retType operator()(typename Gtype::argType x) {
        return f(g(x));
    }
};

int main() {
    auto d = DivideBy(2);
    auto t = Truncate();
    auto c1 = Compose(d, t);
    auto c2 = Compose(t, d);
    std::cout << c1(100.7) << "\n";
    std::cout << c2(11) << "\n";
}
Run Code Online (Sandbox Code Playgroud)

演示.

而不是使用类似Java的初始化Type *var = new Type(args);,只需使用值(auto var = Type(args);Type var(args)).C++不是Java.
请注意,您甚至不需要将模板参数指定为Compose:它们是从构造函数参数中推导出来的.

  • @ paulsm4那是另一场辩论.`auto`是我真正喜欢*关于现代C++的事情之一.而且我有争议.我不介意你不喜欢在其他语言中使用"auto"和类似的东西,但这不是真正的重点. (2认同)