首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复制std::功能还是增强功能::功能?

复制std::功能还是增强功能::功能?
EN

Stack Overflow用户
提问于 2014-06-03 13:43:11
回答 2查看 1.2K关注 0票数 3

如何复制std::functionboost::function

我正在与C++03一起编译,并且积极地避免boost

首先,我试图将类方法作为常规函数指针来处理。我学到关于std::functionboost::function的努力。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-03 16:25:02

可以使用如下声明创建指向成员函数的预C++11函数指针:

代码语言:javascript
复制
ReturnType (ClassType::*func_ptr)() = &ClassType::function;

并使用(instance.*func_ptr)()类的一个实例调用它。例如。

代码语言:javascript
复制
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()),这个示例就能工作。

代码语言:javascript
复制
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;
};

您还可以创建一个帮助函数来创建自动推断成员类型的包装器。

代码语言:javascript
复制
/* 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);
}

现在您可以使用它了,例如:

代码语言:javascript
复制
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编译的这个现场演示

注意:如果需要的话,您可以轻松地修改包装类来存储实例的副本。

票数 3
EN

Stack Overflow用户

发布于 2014-06-03 14:03:31

您应该能够使用TR1的函数和绑定头:

代码语言:javascript
复制
#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();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24016793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档