gpt4 book ai didi

C++ 是否有可能拥有一个包含具有不同类型参数的专用模板对象的容器?

转载 作者:搜寻专家 更新时间:2023-10-31 01:16:49 24 4
gpt4 key购买 nike

我有一个可以(或必须)专门化的模板化类参数。我想将所有参数放在一个容器中。如果我的参数是用不同类型实例化的,该怎么做?

在 Container 类中,我想要有一个来自不同类型(int、double、...)或类似东西的 vector ,这似乎是不可能的。

如果Parameter 类派生自基类,则Container 可以将vect 声明为vector 。但在这种情况下,我们无法在 Container::foo 中执行任何特定操作。

下面是我的源代码示例。我的参数之一是与 ostream 不兼容的 QString。

感谢您的评论。



#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();
}



最佳答案

正确的解决方案是为基类编写足够好的接口(interface),这样你就可以做你需要做的一切:

class Base {
public:
virtual void *GetVal() const=0;
virtual void SetVal(void *ptr)=0;
virtual std::string Type() const=0;
virtual std::string GetAsString() const=0;
};

虽然这可能不是您想要的,但它仍然允许将值从一个参数传递到下一个参数。一旦你想要实际值,你就需要知道编译时的类型。该类型的 Switch-case 可能有助于使其运行时。

关于C++ 是否有可能拥有一个包含具有不同类型参数的专用模板对象的容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8749380/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com