2013-02-15 70 views

回答

2

这意味着,如果你创建bind<>类型的对象,你可以申请该函数调用操作到该对象。

像这样:

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

片断代码可能会打印 “真” 的标准输出。

1

如果你有一个叫foo类,我敢肯定,你明白它的意思来调用类型的对象的成员函数:

foo f; 
f.bar(); 

你也可以理解,你可以重载某些操作。例如,你可以重载operator+foo,这样你可以做这样的事情:

foo f, g; 
f + g; 

现在你也可以重载operator()的一类,它允许你调用它,仿佛它是一个函数:

foo f; 
f(); 

是的,f不是函数,但它是类类型的对象,它重载operator()。这样做的类类型称为函子或函数对象。

在你给出的例子中,bind是一个仿函数。当你创建一个这种类型的对象时,你可以把它称为一个函数,传递给它一个const T&,它会返回给你一个booloperator()的实现实际上调用了存储在comp中的函数,并将其传递给operator(),aT对象以及类型为T的成员对象v

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

这不仅更短,而且(在lea一旦你习惯了它)比使用std::lessbind将功能放在一起简单得多。它通常不会在运行时效率上产生任何影响 - lambda基本上是生成类模板的“简写”方式,所以它生成的结果与使用bind的代码非常相似。