如何复制std::function或boost::function
我正在与C++03一起编译,并且积极地避免boost。
首先,我试图将类方法作为常规函数指针来处理。我学到关于std::function和boost::function的努力。
发布于 2014-06-03 16:25:02
可以使用如下声明创建指向成员函数的预C++11函数指针:
ReturnType (ClassType::*func_ptr)() = &ClassType::function;并使用(instance.*func_ptr)()类的一个实例调用它。例如。
struct Foo {
bool memberFunc() { return true; }
};
int main() {
typedef bool (Foo::*member_func_t)(); // Typedef member func pointer type.
member_func_t func_ptr = &Foo::memberFunc; // Declare function pointer.
Foo foo; // Create foo object.
(foo.*func_ptr)(); // Call member func using instance.
}如果只需要创建指向成员函数的指针,就可以重新创建要查找的泛型属性(我也读了你的另一个问题)。如果在非成员函数指针中混合使用,它将无法工作。
通过使用模板和从公共非模板基类派生的包装类,您可以包装一个成员函数指针,指向任何类类型的一个成员。基类创建一个公共类型,与包装函数指针所属的类无关。如果您想要将包装器存储在同一个容器中,这可能很有用。
只要函数签名始终是相同的(在本例中它固定为bool()),这个示例就能工作。
struct func_base {
virtual ~func_base() {};
virtual bool operator()() const = 0;
};
template <typename C>
class func_wrapper : public func_base {
public:
typedef bool (C::*member_func_ptr_t)();
func_wrapper(member_func_ptr_t func_ptr, C* instance_ptr)
: m_func_ptr(func_ptr), m_instance_ptr(instance_ptr) {}
bool operator()() const { return (m_instance_ptr->*m_func_ptr)(); }
private:
member_func_ptr_t m_func_ptr;
C* m_instance_ptr;
};您还可以创建一个帮助函数来创建自动推断成员类型的包装器。
/* This function returns a pointer to dynamically *
* allocated memory and it is thus the callers *
* responsibility to deallocate the memory!! */
template <typename C>
func_base* make_wrapper(bool (C::*func_ptr)(), C* instance_ptr) {
return new func_wrapper<C>(func_ptr, instance_ptr);
}现在您可以使用它了,例如:
struct Bar { // Define some other class with member function.
bool memberFunc() { return false; }
};
int main() {
Foo foo; // Create object instances.
Bar bar; // ----------||-----------
std::deque<func_base*> d; // Deque storing pointers to base class.
// Push pointer to any member func.
d.push_back(make_wrapper(&Foo::memberFunc, &foo));
d.push_back(make_wrapper(&Bar::memberFunc, &bar));
for (std::deque<func_base*>::iterator it = d.begin(); it != d.end(); ++it) {
(**it)(); // Call all functions in deque.
}
for (std::deque<func_base*>::iterator it = d.begin(); it != d.end(); ++it) {
delete *it; // REMEMBER to destroy wrappers pointed to!!
}
}这将使用C++03编译器进行编译。参见用gcc 4.3.2编译的这个现场演示。
注意:如果需要的话,您可以轻松地修改包装类来存储实例的副本。
发布于 2014-06-03 14:03:31
您应该能够使用TR1的函数和绑定头:
#include <tr1/functional>
#include <string>
#include <sstream>
struct AddX {
template <typename> struct result { typedef std::string type; };
std::string operator()(int a, int b) const {
std::ostringstream oss;
oss << (a + b);
return oss.str();
}
};
int main() {
using namespace std::tr1;
function<std::string(int)> foo = bind(AddX(), 999, placeholders::_1);
return foo(1).length();
}https://stackoverflow.com/questions/24016793
复制相似问题