用于删除指针的c ++ functor似乎有效

时间:2011-08-17 12:56:58

标签: c++ pointers functor

在其他地方,建议使用仿函数来删除向量中的指针

struct DeleteFromVector
{
    template <class T>
    void operator() ( T* ptr) const
    {
            delete ptr;
    }
};

使用

进行调用
std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());

我写了类似的东西(虽然最初没有在结构中巧妙地移动模板):

    struct DeleteObj 
    {
        template<typename ObjType>
        inline void operator() (ObjType obj)
        { 
            delete obj; 
            obj = NULL; 
        };
    };

在调试器中单步执行它似乎工作,即obj被识别为指针而没有任何崩溃。

我有点困惑为什么两者都有效,并且还希望听到有关使用const和内联的意见。

谢谢, 罗伯特

6 个答案:

答案 0 :(得分:3)

第一个是首选,因为只有在向量元素类型是指针时才会编译。如果向量元素类型可以转换为非void指针,则第二个将编译,可能会产生灾难性后果。

Functors通常被声明为const,通常不会有所作为,但它也不会花费任何费用。

答案 1 :(得分:2)

它有效,因为ObjType推断为WhateverTypeYouHaveInYourVector *。使用第一个解决方案,T推断为WhateverTypeYouHaveInYourVector。后者更好,因为它要求参数是一个指针,而在你的解决方案中,参数可以是任何东西,甚至是不可删除的东西。

顺便说一下,obj = NULL没用,因为你按值取参数。因此,将设置为null的指针是函数的本地副本,而不是向量中包含的副本。您可以改为引用指针:

struct Deleter
{
    template <typename T>
    void operator()( T * & ptr) const
    {
        delete ptr;
        ptr = 0;
    }
};

答案 2 :(得分:2)

  • 为什么两者都有效:如果您致电operator()(U*),则第一个与T = U匹配,第二个与ObjType = U*匹配。

  • const:这只是说你没有修改任何成员,但由于你的结构是空的,这没什么区别。有些算法可能将其函子作为const,因此只允许访问常量成员函数(但不能在for_each中)。无论如何,你的成员函数也可能是静态的,因为没有状态。

  • 内联只是一个编译器提示;无论如何,建筑都会被内联。无论如何,类定义中的成员定义都是隐式内联的。

答案 3 :(得分:2)

为什么两个模板都有效?

在第一个模板中,您将Obj*传递给采用T*的模板方法,以便编译器推断TObj

在第二个模板中,您将Obj*传递给采用T的模板方法,以便编译器推断TObj*


使用inline

inline在那里是多余的,因为类定义中的成员函数已定义是隐式的inline


使用const

如果可能,Functors应将operator()声明为const。这是因为通过非const引用传递临时是非法的。除非std::for_each(...,..., Functor());具有Functor,否则对operator(T)const的调用可能无法编译。

由于Microsoft编译器实现了非标准扩展,允许通过非const引用传递临时值并默认启用此非标准行为,因此该问题变得混乱。

答案 4 :(得分:1)

两者都有效,因为两者都正确地推导出了模板参数,只是在一种情况下它是一个指针,在另一种情况下它是指向的类型,因为签名已经包含*

内联在这里是多余的,因为函数已经内联。设置obj = NULL也没用,因为它只将指针的本地副本设置为0,而不是 - 很可能 意图 - 向量中的条目。

答案 5 :(得分:0)

第二个例子可能不起作用,因为你没有指出它:

inline void operator() (ObjType* obj)

这应该有效,就像上面的例子一样。

inline是一个编译器优化建议,可以将函数完全复制到每个被调用的地方。

const关键字有很多用途,具体取决于您使用它的位置。在您的情况下(在第一个示例中),意味着调用该方法的类或对象不得更改,并且可以在const上下文中使用。