开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜