用于删除指针的c++函函数似乎有效
c++ functor for deleting pointers seems to work
对于用于删除vector
中的指针的函子,建议使用以下方法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的意见。
谢谢,罗伯特。
首选第一种方法,因为它仅在vector元素类型为指针时才能编译。如果vector元素类型可转换为非空指针,则第二种方法将编译,这可能会导致灾难性的后果。
函子通常声明为const,通常没有什么区别,但也不需要任何开销
为什么两个模板都可以工作?
在第一个模板中,您将Obj*
传递给接受T*
的模板方法,因此编译器推断T
为Obj
。
在第二个模板中,您将Obj*
传递给接受T
的模板方法,因此编译器推断T
是Obj*
。
inline
inline
在这里是多余的,因为在类定义中定义的成员函数是隐式的inline
。
使用const
函子的operator()
应该声明为const
。这是因为传递临时的非const引用是非法的。对std::for_each(...,..., Functor());
的调用可能无法编译,除非Functor
有一个operator(T)const
。
这个问题被Microsoft编译器实现的一个非标准扩展所混淆,该扩展允许通过非const引用传递临时对象,并在默认情况下启用这种非标准行为。
-
为什么两者都工作:如果你调用
operator()(U*)
,第一个匹配T = U
,第二个匹配ObjType = U*
。 -
const
:这只是说你没有修改任何成员,但是因为你的结构是空的,这没有什么区别。有些算法可以将其函子作为const,因此只允许访问常量成员函数(但在for_each
中不允许)。在任何情况下,你的成员函数最好是静态的,因为没有状态。 -
内联只是一个编译器提示;无论如何,构造都可能是内联的。类定义中的成员定义无论如何都是隐式内联的。
它可以工作,因为ObjType
被推断为WhateverTypeYouHaveInYourVector *
。对于第一个解,T
推导为WhateverTypeYouHaveInYourVector
。后者更好,因为它要求实参是一个指针,而在您的解决方案中,实参可以是任何东西,甚至是不可删除的东西。
顺便说一下,obj = NULL
是无用的,因为您按值接受参数。因此,将被设置为空的指针是函数的本地副本,而不是vector中包含的指针。可以使用指针的引用:
struct Deleter
{
template <typename T>
void operator()( T * & ptr) const
{
delete ptr;
ptr = 0;
}
};
两者都有效,因为它们都正确地推导了模板参数,在一种情况下它是指针,在另一种情况下它是指向的类型,因为签名已经包含了*
inline在这里是多余的,因为函数已经是内联的。另外,设置obj = NULL
是无用的,因为它只将指针的本地副本设置为0,而不是——正如可能的那样
第二个例子可能不起作用,因为您没有从中创建一个指针:
inline void operator() (ObjType* obj)
这应该可以工作,就像上面的例子。
inline
是一个编译器优化建议将函数完全复制到每个调用它的地方。
const
关键字有许多用途,这取决于您在哪里使用它。在你的例子中(在第一个例子中),这意味着调用方法的类或对象不能改变,可以在const
上下文中使用。
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 递归函数有效,但无法记忆
- 将此布尔值传递给此函数的最有效方法是什么?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 我如何知道作为参数的size_t在函数中是否有效?
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 文本 RPG - 使用函数检查有效的输入
- 将 C 函数转换为 C++ 以检查数字是否有效
- 函数参数的名称与调用函数时使用的变量相同是否有效?
- 为什么使用不匹配的参数调用重载函数仍然有效
- 在函数中按值传递 unordered_map/unordered_set 是否有效? C++
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- 为什么即使直接构造函数有效,template_back也会失败
- 不太清楚为什么我的递归链表删除函数有效?我很想解释一下
- 调用不带参数的构造函数有效,使用参数则无效。为什么?
- 为什么其中一个模板静态函数有效,而另一个不起作用
- 混合按引用传递和按值传递到可变参数模板函数有效
- 如何专门化模板类方法基于类型特征?使用std::enable_if对非类函数有效,但对类方法无效