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

发布于 2024-11-30 13:00:23 字数 659 浏览 1 评论 0原文

向量中的指针,

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 和 inline 的意见。

谢谢, 罗伯特

Elsewhere the following was suggested for a functor for deleting pointers in a vector

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

to be called using

std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());

I had written something similar (though originally without the clever moving of the template within the struct):

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

Stepping through it in the debugger it seems to work, i.e. obj is recognized as a pointer and nothing crashes.

I'm a bit confused as to why both work, and would also like to hear opinions on the use of const and inline in these.

Thanks,
Robert

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

巷雨优美回忆 2024-12-07 13:00:23

第一个是首选,因为它仅在向量元素类型是指针时才会编译。如果向量元素类型可转换为非空指针,则第二个将编译,这可能会带来灾难性的后果。

函子通常被声明为 const,通常不会产生任何影响,但也不会花费任何成本。

The first is to be preferred since it will only compile if the vector element type is a pointer. The second would compile if the vector element type is convertable to a non-void pointer, with presumably disasterous consequences.

Functors are normally declared const, doesn't often make a difference but it doesn't cost anything either.

谈情不如逗狗 2024-12-07 13:00:23

为什么两个模板都有效?

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

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


使用内联

内联是多余的,因为类定义中定义的成员函数是隐式的内联。


使用const

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

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

Why do both templates work?

In the first template, you pass an Obj* to a template method taking a T* so the compiler deduces that T is Obj.

In the second template, you pass an Obj* to a template method taking a T so the compiler deduces that T is Obj*.


Use of inline

The inline is redundant there, as member functions defined inside the class definition are implicitly inline.


Use of const

Functors should have their operator() declared constif possible . This is because it is illegal to pass a temporary by non-const reference. A call to std::for_each(...,..., Functor()); may not compile unless Functor has an operator(T)const.

This issue is muddied by the fact that the Microsoft compilers implement a non-standard extension allowing passing temporaries by non-const reference and enable this non-standard behaviour by default.

岁月蹉跎了容颜 2024-12-07 13:00:23
  • 为什么两者都有效:如果您调用 operator()(U*),第一个匹配 T = U,第二个匹配 ObjType = U *.

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

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

  • Why both work: If you call operator()(U*), the first one matches T = U, the second one matches ObjType = U*.

  • const: that just says that you're not modifying any members, but since your structs are empty, this makes no difference. Some algorithms may take their functors as const and hence allow only access to constant member functions (but not in for_each). In any event, your member function might as well be static, since the there's no state.

  • inlining is just a compiler hint; chances are that construction would be inlined no matter what. Member definitions inside class definitions are implicitly inline anyway.

晒暮凉 2024-12-07 13:00:23

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

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

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

It works because ObjType is deduced to be WhateverTypeYouHaveInYourVector *. With the first solution, T is deduced to be WhateverTypeYouHaveInYourVector. The latter is better because it requires the argument to be a pointer, while in your solution, the argument can be anything, even something that is not deletable.

By the way, obj = NULL is useless because you take the parameter by value. Consequently, the pointer that will be set to null is the copy local to the function, not the one contained in the vector. You could take a reference to a pointer instead:

struct Deleter
{
    template <typename T>
    void operator()( T * & ptr) const
    {
        delete ptr;
        ptr = 0;
    }
};
埋葬我深情 2024-12-07 13:00:23

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

内联在这里是多余的,因为该函数已经是内联的。另外,设置 obj = NULL 是没有用的,因为它仅将指针的本地副本设置为 0,而不是像可能的那样
预期——向量中的条目。

Both work because both properly deduce the template parameter, just in one case it is a pointer, in the other it is the type that is being pointed to, because the signature already contains the *

inline is redundant here, as the function is inline already. Also setting the obj = NULL is useless since it sets only your local copy of the pointer to 0, not -- as was probably
intended -- the entry in the vector.

鹊巢 2024-12-07 13:00:23

第二个示例可能不起作用,因为您没有从中创建指针:

inline void operator() (ObjType* obj)

这应该起作用,就像上面的示例一样。

内联是编译器优化建议,将函数完全复制到调用它的每个地方。

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

The second example may not work, because you did not make a pointer out of it:

inline void operator() (ObjType* obj)

This should work, just as the upper example.

The inline is a compiler optimization suggestion to completely copy the function to every place it is called.

The const keyword has many uses, depending on where you use it. In your case (in the first example) it means, that the class or object on which the method is called shall not alter and can be used in const contexts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文