Reputation: 322
It has been a while since I have used templates with C++, but now I really need them.
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.
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’
Upvotes: 0
Views: 1210
Reputation: 2713
If you want storage that can store more than one type of value you can try something like this: 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.
Upvotes: 2
Reputation: 322
I found a solution which is kinda what I was looking for, but I'm not sure if this is good practice. :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;
};
Upvotes: -3
Reputation: 33691
Maybe try to use 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
Upvotes: 2
Reputation: 227518
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
:
class storage {
public:
inline void push(problem::data<int> * data) {
this->VData.push_back(data);
}
private:
std::vector<problem::data<int> *> VData;
};
Upvotes: 1