如何在C ++中重载函数调用?

时间:2013-02-15 20:38:56

标签: c++ struct overloading operator-keyword

我读到函数call()也可以重载。 http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

以下是什么意思?

有效。

template<typename T, typename Comp>
struct bind{
    T v;
    Comp comp;
    bool operator()(const T& b){
        return comp(b,v);
    }
};

int main(){
    bind<int, less<int> > b;
    b.v = 2;
    cout << b(3) << "\n";
}

3 个答案:

答案 0 :(得分:2)

这意味着如果您创建类型为bind<>的对象,则可以将函数调用运算符应用于该对象。

像这样:

bind<int, std::less<int>> b;
b.v = 2;
std::cout << b(1) << "\n";

该片段可能会在标准输出上打印“true”。

答案 1 :(得分:1)

如果您有一个名为foo的类,我确信您了解调用该类型对象的成员函数意味着什么:

foo f;
f.bar();

您可能还了解可以超载某些操作。例如,您可以为operator+重载foo,以便您可以执行以下操作:

foo f, g;
f + g;

现在你也可以为一个类重载operator(),这允许你像调用它一样调用它:

foo f;
f();

是的,f不是函数,但是类型的对象重载operator()。执行此操作的类类型称为仿函数或函数对象。

在您给出的示例中,bind是一个仿函数。当您创建该类型的对象时,您可以将其称为函数,并将其传递给const T&,它将返回bool给您。 operator()的实现实际上调用了存储在comp中的函数,并将传递给Toperator()的{​​{1}}对象和成员对象{ {1}}类型的{1}}。

答案 2 :(得分:1)

就目前而言,除了“语法错误”之外,它并不意味着什么。例如:

template<T, Op>

这是不允许的。对于每个模板参数,您需要指定它是一种类型(使用class还是typename)还是非类型参数,例如int。由于明显的意图是这两个都应该是类型参数,你需要类似的东西:

template <class T, class Op>

或:

template <typename T, typename Op>

对于这种情况,classtypename之间的含义没有区别。

struct bind{
    T v;

离开v未初始化将导致未定义的行为,因此您可能不希望允许这样做。您通常会通过添加以T为参数的构造函数并将v初始化为该值来阻止它:

bind(T const &v) : v(v) {}

当您包含这样的构造函数时,编译器不会自动生成默认构造函数,因此不再可能创建bind未初始化v的对象 - 正是我们想要的。

虽然创建了comp对象:

Op comp;

是相当无害的,也是非常不必要的。您也可以与使用Op()创建的临时实例进行比较,在这种情况下:

bool operator()(const T& a){
    return comp(a,v);
}

......会变成这样的东西(简单地删除Op comp;):

bool operator()(T const &a) { 
    return Op()(a, v);
}

即使有更正,我也会认为此代码已过时。在C ++ 98/03中,在需要为算法提供仿函数的情况下它会很有用,例如:

std::remove_copy_if(a.begin(), a.end(), bind<int, 
                    std::back_inserter(b),
                    bind<int, std::less<int> >(5));

...将a的数字复制到b,删除少于5的数字。

但是,在C ++ 11中,大多数(如果不是全部)使用这个bind应该写成lambda而不是,所以上面的位会变成这样:

std::remove_copy_if(a.begin(), a.end(), bind<int, 
                    std::back_inserter(b),
                    [](int x) { return x < 5; });

这不仅更短,而且(至少在你习惯之后)比使用std::lessbind组合一个函数要简单得多。它通常不会对运行时效率产生任何影响 - lambda基本上是生成类模板的“简写”方式,因此它生成的内容最终与使用bind的代码非常相似。 / p>