这似乎应该经常被问及回答,但我的搜索功能让我失望了.
我正在编写一个函数,我想接受某种通用的可调用对象(包括裸函数,手动仿函数对象bind
,或std::function
),然后在算法深度(即lambda)中调用它.
该函数目前声明如下:
templatesize_t do_something(const T& a, const F& f) { T internal_value(a); // do some complicated things // loop { // loop { f(static_cast (internal_value), other_stuff); // do some more things // } // } return 42; }
我通过引用接受仿函数,因为我想保证它不会在函数入口时被复制,因此实际调用了对象的相同实例.它是一个const引用,因为这是接受临时对象的唯一方法(这在使用手动仿函数时很常见bind
).
但是这需要将functor实现operator()
为const.我不想要那个; 我希望它能够接受两者.
我知道我可以声明这个方法的两个副本,一个接受它作为const,一个接受非const,以便涵盖这两种情况.但是我不想这样做,因为注释隐藏了很多我不想复制的代码(包括一些循环结构,所以我不能在不移动问题的情况下将它们提取到辅助方法) .
我也知道const_cast
在调用它之前我可能会欺骗和非const的仿函数,但这感觉有潜在危险(特别是如果函子故意实现const和非const调用操作符,则会调用错误的方法).
我已经考虑过接受函子作为std::function
/ boost::function
,但这对于应该是一个简单的问题来说是一个重要的解决方案.(特别是在仿函数不做任何事情的情况下.)
有没有"正确"的方法来满足这些要求而不是复制算法?
[注意:我更喜欢不需要C++ 11的解决方案,尽管我也对C++ 11的答案感兴趣,因为我在两种语言的项目中都使用类似的结构.