C++ -- In which case the compiler can deduce the type
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*> vw开发者_StackOverflow社区pB;
// populate vwpB;
// Do not need to specify the TYPE 'Widget'
for_each(vwpB.begin(), vwpB.end(), DeleteObjectB()); // case II
My question is as follows:
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?
Thank you
The first case features a class template. The second case features a function template. That is the one distinction.
Simple: In the first case, you got nothing to deduce the template type from... how would you? :P In general, for class templates you need to specify the type and (correct me if I'm wrong) can never deduce it.
In your second case, the compiler can deduce the type because you pass an object of type Widget*
to that operator()
. That's how the compiler sees "Ah, incoming Widget*
here, now I know what T should be!"
// Call:
DeleteObject deleter;
Widget* mypwidget;
deleter(mypwidget);
// ^^^^^^^^^ -- of type `Widget*`, so `T` can be substituted with `Widget*`
In case II, sometimes operator()
is called statically polymorphic.
As you mentioned, probably case II is handier in many cases since compiler
can deduce the argument type.
However, in current C++, sometimes polymorphic operator()
doesn't suit.
For example, if the operator()
has the signature:
struct DeleteObjectB {
template<typename T>
T operator() (const T*) ...
then we cannot pass this DeleteObjectB
to some binder like std::bind1st
,
boost::bind
or similar one.
Those binders require nested typedef
result_type
as the resultant
type of operator()
.
So, in this case, we need case I.
精彩评论