【发布时间】:2012-02-03 16:24:06
【问题描述】:
我有一个可以(或必须)专门化的模板化类参数。 我想把我所有的参数放在一个容器中。 如果我的参数被实例化为不同的类型怎么办?
在 Container 类中,我希望拥有一个来自不同类型(int、double、...)的向量
如果 Parameter 类派生自基类,则 Container 可以将 vect 声明为 vector
以下是我的源示例。我的参数之一是与 ostream 不兼容的 QString。
感谢您的 cmets。
#include <QString>
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define P(a) cout << #a << ":" << a << endl
/*
class Base {
};
*/
template<typename T> class Parameter /*: public Base */ {
private:
T val;
public:
void setVal(const T &val) {
this->val = val;
}
const T &getVal() {
return val;
}
string getFoo() {
stringstream s;
s << val;
return s.str();
}
};
template<>
string Parameter<QString>::getFoo() {
stringstream s;
s << val.toStdString();
return s.str();
}
class Container {
public:
void push_back(Parameter *base) {
vect.push_back(base);
}
void foo() {
/* do something with the parameters */
}
private:
vector<Parameter*> vect;
};
int main() {
Parameter<int> pi;
Parameter<QString> ps;
pi.setVal(10);
ps.setVal("QString");
P(pi.getVal());
P(ps.getVal().toStdString());
P(pi.getFoo());
P(ps.getFoo());
Container container;
container.push_back(&pi);
container.push_back(&ps);
}
非常感谢你们。我会听从你的建议并使用 boost::any。 这是更新版本:
#include <boost/any.hpp>
#include <QString>
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define P(a) cout << #a << ":" << a << endl
template<typename T> class Parameter {
private:
T val;
public:
void setVal(const T &val) {
this->val = val;
}
const T &getVal() {
return val;
}
string getFoo() {
stringstream s;
s << val;
return s.str();
}
};
template<>
string Parameter<QString>::getFoo() {
stringstream s;
s << val.toStdString();
return s.str();
}
class Container {
public:
void push_back(boost::any base) {
vect.push_back(base);
}
void foo() {
cout << "do something with the parameters\n";
for (vector<boost::any>::iterator i = vect.begin(); i != vect.end(); ++i) {
boost::any a = (*i);
if (a.type() == typeid(Parameter<int>*)) {
Parameter<int> *ai = boost::any_cast<Parameter<int> *>(a);
cout << ai->getFoo() << endl;
} else if (a.type() == typeid(Parameter<QString>*)) {
Parameter<QString> *aq = boost::any_cast<Parameter<QString> *>(a);
cout << aq->getFoo() << endl;
} else {
cout << "unknown type:" << a.type().name() << endl;
}
}
}
private:
vector<boost::any> vect;
};
int main() {
Parameter<int> pi;
Parameter<QString> ps;
pi.setVal(10);
ps.setVal("QString");
P(pi.getVal());
P(ps.getVal().toStdString());
P(pi.getFoo());
P(ps.getFoo());
Container container;
container.push_back(&pi);
container.push_back(&ps);
container.foo();
}
【问题讨论】:
-
Qstring“与ostream不兼容”是什么意思,它与这个问题有什么关系?您是否尝试调用 Parameter
::getFoo()?如果有意义,您可以提供一种方法让 operator -
您到底想做什么?使用 Base 如何不能解决您的问题?听起来您想要跨多种类型通用的东西,同时具有特定于该类型的一些功能(“我们不能在 Container::foo 中做任何特定的事情”) - 我不确定如何在不向下转换的情况下有意义地实现这一点。
-
@bacar 模板类中的 getFoo() 不适用于 QString。我们必须使用:s << val.toStdString().
-
如果你为 QString 提供一个操作符. 提供模板特化
-
是的,您适合 QString 的运算符。这只是专业化的一个例子。 Container 类的问题仍然存在:如何在容器中存储任何类型的实例化参数?有可能吗?
标签: c++ templates containers