函数在C++中永远不能是抽象的吗
Can a Functor never be abstract in C++?
通常,模板参数可以是抽象类,下面的程序也显示了这一点。但似乎排序中的比较函子一定不是抽象的。至少以下内容不能在VC++11和Oracle Studio 12上编译。
#include <vector>
#include <algorithm>
class Functor
{
public:
virtual bool operator()(int a, int b) const = 0;
};
class MyFunctor: public Functor
{
public:
virtual bool operator()(int a, int b) const { return true; }
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<Functor> fv; // template of abstract class is possible
vector<int> v;
MyFunctor* mf = new MyFunctor();
sort(v.begin(), v.end(), *mf);
Functor* f = new MyFunctor();
// following line does not compile:
// "Cannot have a parameter of the abstract class Functor"
sort(v.begin(), v.end(), *f);
return 0;
}
现在,我想知道这是函子参数的一般性质,还是取决于STL实现?有办法得到我想做的事吗?
函数通常需要可复制。多态基类通常不可复制,抽象基类永远不可复制。
更新:感谢@ahenderson和@ltjax的评论,这里有一个非常简单的方法来生成一个包含原始多态引用的包装器对象:
#include <functional>
std::sort(v.begin(), v.end(), std::ref(*f));
// ^^^^^^^^^^^^
std::ref
的结果是std::refrence_wrapper
,这正是您所需要的:一个具有值语义的类,它包含对原始对象的引用。
函子被复制的事实让很多人感到困惑,他们想在函子内部积累一些东西,然后想知道为什么结果不正确。函子真的应该对外部对象进行引用。也就是说:
糟糕不会像你预期的那样工作;函子可能被任意复制:
struct Func1 {
int i;
Func1() : i(0) { }
void operator()(T const & x) { /* ... */ }
};
Func1 f;
MyAlgo(myContainer, f);
好:您提供累加器;复制函子是安全的:
struct Func2 {
int & i;
Func2(int & n) : i(n) { }
void operator()(T const & x) { /* ... */ }
};
int result;
MyAlgo(myContainer, Func2(result));
正如Kerrek所说,你不能直接这么做:
但只要间接一级,你就没事了。
struct AbstractFunctor
{
AbstractFunctor( Functor * in_f ): f(in_f) {}
// TODO: Copy constructor etc.
Functor * f;
bool operator()(int a, int b) const { return (*f)(a,b); }
};
int main()
{
vector<int> v;
Functor * mf = new MyFunctor();
sort(v.begin(), v.end(), AbstractFunctor(mf) );
}
正如Kerrek和Michael Anderson所说,你不能直接这么做。正如Michael所展示的,您可以编写一个包装器类。但std::
中也有一个:
sort(v.begin(),
v.end(),
std::bind(&Functor::operator(),
mf,
std::placeholders::_1,
std::placeholders::_2) );
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的for循环不能正确获取argv
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么模板类中的对象不能返回值
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么不能将std :: async用于接收对抽象类作为参数的函数
- 不能将变量声明为类的抽象
- 对抽象类的引用不能传递给线程函数?
- 不能分配抽象类型的对象 - 但类不是抽象的!(C++)
- 函数在C++中永远不能是抽象的吗
- 不能实例化抽象类的对象,但必须返回该类的对象
- 不能分配抽象类型的对象
- 为什么 *从 const 成员函数返回的不能用于调用 C++ 中的其他函数
- C++抽象类的问题(我可以用Java做,但不能用C++!)
- 我不能在我的抽象数据类型中使用队列
- 如果函数是从抽象类派生的,则不能用具体的类指针调用该函数
- 需要解决的限制:抽象类不能用于返回类型