从类本身运行函数

时间:2019-01-01 08:39:36

标签: c++

我正试图在类中传递任何函数类型,这些函数类型将在其中存储以供以后使用。这个想法是通过使用类中的someMethod函数来运行类中的函数。

整个代码是:

#include <iostream>
#include <vector>

namespace problem {
    class storage {
        struct data_base {};

        template <class K>
        struct data: data_base {
            data(const K& v): value_(v) {}
            K value_;
        };

        typedef std::vector<data_base*> container_type;

    public:
        ~storage() {
            while(!this->VData.empty()) {
                delete this->VData.back();
                this->VData.pop_back();
            }
        }
        template <class P>
        inline void push(P v) {
            this->VData.push_back(new data<P>(v));
        }

        template <class P>
         P &push2(void) {
            static_cast<data<P>*>(this->VData[1])->value_(1,1);
        }

        template < class P = void *>
        void someMethod(void)
        {
             // ERROR HERE: Called object type 'void *' is not a function or function pointer
             static_cast<data<P>*>(this->VData[0])->value_(0,0);
        }


        template <class P>
        P &get(int i) {
            return static_cast<data<P>*>(this->VData[i])->value_;
        }
    private:
        container_type VData;
    };
}

bool function(int x, int y)
{
    std::cout << "hello world1"<< std::endl;
    return x < y;
}

bool function2(int x, int y)
{
    std::cout << "hello world2"<< std::endl;
    return x < y;
}

int main(int argc, const char * argv[]) {
    problem::storage testStorage;
    testStorage.push(&function);
    testStorage.push(&function2);

    testStorage.someMethod<>();
    return 0;
}

我收到此错误:被调用的对象类型'void *'不是函数或函数指针。我不知道如何实现我的目标。我希望比我更有知识的人可以帮助我解决此问题并逐步解释,以便我可以学习。

2 个答案:

答案 0 :(得分:1)

根据Jesper Juhl的建议,您可以使用std::vector<std::function>进行此操作。您必须牢记的一件事。因为您要创建std::function的向量,所以对于一个存储对象,所存储函数的签名将相同。

您可以执行以下操作:

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

namespace problem {
    // forward declaration
    template<typename T, typename ...U>
    class storage;

    template<typename T, typename ...U>
    class storage<T(U...)> {
        using container_type = std::vector<std::function<T(U...)> >;

    public:
        void push(std::function<T(U...)> v) {
            this->VData.push_back(v);
        }

        T callMethod(int i, U &&...args) {
            // TODO: Bounds check
            return this->VData[i](std::forward<U>(args)...);
        }

    private:
        container_type VData;
    };
}

bool function1(int x, int y) {
    std::cout << "hello world1"<< std::endl;
    return x < y;
}

bool function2(int x, int y) {
    std::cout << "hello world2"<< std::endl;
    return x < y;
}

int main(int argc, const char * argv[]) {
    problem::storage<decltype(function1)> testStorage;
    testStorage.push(function1);
    testStorage.push(function2);

    cout << testStorage.callMethod(0, 1, 1);
    cout << testStorage.callMethod(1, 1, 1);

    return 0;
}

输出:

hello world1
0
hello world2
0

答案 1 :(得分:0)

我建议您在data_base中添加一个纯虚拟操作符(),在数据中实现它,然后使someMethod成为常规函数而不是模板。

现在,您需要知道要调用的函数的签名,以便正确地调用someMethod,通过将operator()虚拟化,可以在已经知道存储函数类型的上下文中进行调用(即是来自数据内部

本身)。