简体   繁体   English

将模板类作为参数传递给类方法,并使用模板类作为矢量模板类型

[英]Passing template class as parameter to class method and using template class as vector template type

It has been a while since I have used templates with C++, but now I really need them. 自从我使用C ++模板以来已经有一段时间了,但现在我真的需要它们。

I reproduced a problem I am having and I don't remember how the solution actually went. 我重现了我遇到的一个问题,我不记得解决方案是如何实现的。

#include <iostream>
#include <vector>

namespace problem {
    template <typename T>
    class data {
        public:
            inline data(T var) {
                this->var = var;
            }
        private:
            T var;
    };

    class storage {
        public:
            inline void push(problem::data<T> * data) {
                this->VData.push_back(data);
            }
        private:
            std::vector<problem::data<T> *> VData;
    };
};

int main() {
    problem::storage * testStorage = new problem::storage();
    problem::data<int> * testData = new problem::data<int>(256);

    testStorage->push(testData);

    delete testData;
    delete testStorage;
    return 0;
}

g++ -Wall problem.cpp gives me the following errors. g ++ -Wall problem.cpp给出了以下错误。

problem.cpp:17:35: error: ‘T’ was not declared in this scope
problem.cpp:17:36: error: template argument 1 is invalid
problem.cpp:21:30: error: ‘T’ was not declared in this scope
problem.cpp:21:31: error: template argument 1 is invalid
problem.cpp:21:34: error: template argument 1 is invalid
problem.cpp:21:34: error: template argument 2 is invalid
problem.cpp: In member function ‘void problem::storage::push(int*)’:
problem.cpp:18:17: error: request for member ‘push_back’ in ‘((problem::storage*)this)->problem::storage::VData’, which is of non-class type ‘int’
problem.cpp: In function ‘int main()’:
problem.cpp:29:28: error: no matching function for call to ‘problem::storage::push(problem::data<int>*&)’
problem.cpp:29:28: note: candidate is:
problem.cpp:17:16: note: void problem::storage::push(int*)
problem.cpp:17:16: note:   no known conversion for argument 1 from ‘problem::data<int>*’ to ‘int*’

I know I can use member templates, but what I do with the vector? 我知道我可以使用成员模板,但是我对矢量做了什么?

template <typename T>
inline void push(problem::data<T> * data) {
    this->VData.push_back(data);
}

If I use the member template then the vector definition will leave these errors. 如果我使用成员模板,那么向量定义将留下这些错误。

problem.cpp:22:30: error: ‘T’ was not declared in this scope
problem.cpp:22:31: error: template argument 1 is invalid
problem.cpp:22:34: error: template argument 1 is invalid
problem.cpp:22:34: error: template argument 2 is invalid
problem.cpp: In member function ‘void problem::storage::push(problem::data<T>*)’:
problem.cpp:19:17: error: request for member ‘push_back’ in ‘this->.VData’, which is of non-class type ‘int’

Maybe try to use boost::any? 也许尝试使用boost :: any?

#include <iostream>
#include <vector>
#include <boost/any.hpp>

namespace problem {
    template <typename T>
    class data {
        public:
            inline data(T var) {
                this->var = var;
            }
        private:
            T var;
    };

    class storage {
        public:
            template<class T>
            inline void push(problem::data<T> * data) {
                this->VData.push_back(data);
            }
        private:
            std::vector<boost::any> VData;
    };
};

int main() {
    problem::storage * testStorage = new problem::storage();
    problem::data<int> * testData = new problem::data<int>(256);

    testStorage->push<int>(testData);

    problem::data<float> * testData1 = new problem::data<float>(1.);
    testStorage->push<float>(testData1);

    delete testData;
    delete testData1;
    delete testStorage;
    return 0;
}

But you need to cast from boost::any to your type before using data from vector 但是在使用vector中的数据之前,你需要从boost :: any转换为你的类型

If you want storage that can store more than one type of value you can try something like this: http://ideone.com/jjuVq 如果您想要存储可以存储多种类型值的存储,您可以尝试这样的方法: http//ideone.com/jjuVq

class storage {
    struct data_base {};

    template <class K> 
    struct data: data_base {
        data(K value): value_(value) {}
        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 &get(int i) { return static_cast<data<P>*>(this->VData[i])->value_; }
private:
    container_type VData;
};

or just use boost::any as a container's value type. 或者只使用boost :: any作为容器的值类型。

Your storage class has a data member that depends on a template parameter, so you should make it a class template: 您的存储类有一个依赖于模板参数的数据成员,因此您应该将其设为类模板:

template <typename T>
class storage {
    public:
        inline void push(problem::data<T> * data) {
            this->VData.push_back(data);
        }
    private:
        std::vector<problem::data<T> *> VData;
};

Otherwise, you could make storage work for a specific type T : 否则,您可以使storage工作为特定类型T

class storage {
    public:
        inline void push(problem::data<int> * data) {
            this->VData.push_back(data);
        }
    private:
        std::vector<problem::data<int> *> VData;
};

I found a solution which is kinda what I was looking for, but I'm not sure if this is good practice. 我找到了一个解决方案,这是我想要的,但我不确定这是不是很好的做法。 :P :P

class storage {
    public:
        template <typename T>
        inline void push(problem::data<T> * data) {
            this->VData.push_back(reinterpret_cast<char*>(data));
        }
        template <typename T>
        inline problem::data<T> * draw() {
            problem::data<T> * data = reinterpret_cast<problem::data<T>*>(VData.back());
            return data;
        }
    private:
        std::vector<char*> VData;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM