问题描述
|
vector<Widget*> vwp;
// populate vwp;
// Do need to specify the TYPE \'Widget\'
for_each(vwp.begin(),vwp.end(),DeleteObject<Widget>()); // case I
template<typename T>
struct DeleteObject: public unary_function<const T*,void> {
void operator() (const T* ptr) const
{
delete ptr;
}
};
///////////////////////////////////////////////////////////
struct DeleteObjectB {
template<typename T>
void operator() (const T* ptr) const
{
delete ptr;
}
};
vector<Widget*> vwpB;
// populate vwpB;
// Do not need to specify the TYPE \'Widget\'
for_each(vwpB.begin(),vwpB.end(),DeleteObjectB()); // case II
我的问题如下:
In case I,we need to specify the type.
In case II,we don\'t need to specify the type.
Is there a general rule that I can follow?
谢谢
解决方法
第一种情况具有类模板。第二种情况具有功能模板。那是一个区别。
,简单:在第一种情况下,您无法从...推论出模板类型。 :P通常,对于类模板,您需要指定类型,并且(如果我错了,请更正我)永远无法推断出它。
在第二种情况下,编译器可以推断出类型,因为您将类型为“ 2”的对象传递给了类型为“ 3”的对象。这就是编译器看到的样子:“啊,在这里输入
Widget*
,现在我知道T应该是!”
// Call:
DeleteObject deleter;
Widget* mypwidget;
deleter(mypwidget);
// ^^^^^^^^^ -- of type `Widget*`,so `T` can be substituted with `Widget*`
,在情况II中,有时operator()
被称为静态多态。
如您所述,自编译器以来,情况II在许多情况下可能更方便
可以推断出参数类型。
但是,在当前的C ++中,有时多态operator()
不适合。
例如,如果“ 3”具有签名:
struct DeleteObjectB {
template<typename T>
T operator() (const T*) ...
那么我们就不能将这10英镑传递给像11英镑这样的活页夹,
boost::bind
或类似的。
这些活页夹要求嵌套typedef
result_type
作为结果
operator()
的类型。
因此,在这种情况下,我们需要案例I。