对于noob问题感到抱歉,但我似乎无法理解C ++的静态性质。问题:我有一个返回枚举的类,依赖于它我必须使用另一个类转换所述类并返回一个向量。在代码中:
enum TYPES { TYPE_A, TYPE_B, TYPE C }
class A {
TYPES getType() {}
}
class B : public A {}
class C : public A {}
class D : public A {}
std::vector<?> convert_to_vector(const A& a) {
// depending on what enum is returned by a.getType()
// I have to convert a into B, C, or D class and return std::vector of
// an appropriate type, e.g. int for B, float for C, etc.
}
int main() {
A a;
auto v = convert_to_vector(a);
}
最简单的方法是使用switch(a.getType())
,但我在每种情况下都有不同的返回类型,并且使用auto
作为返回类型不起作用。我已经尝试过模板和模板规范,但它们不接受a.getType()
返回的运行时变量。我想必须有一些我在这里忽略的简单解决方案,但是我已经完成了这个想法,并且会对任何指针感激不尽。
谢谢!
答案 0 :(得分:2)
您无法在运行时更改C ++函数的返回类型。但您可以使用variant类型:
std::variant<std::vector<int>, std::vector<float>> convert_to_vector(const A& a) {
if (a.getType() == TYPE_B)
return std::vector<int>();
if (a.getType() == TYPE_C)
return std::vector<float>();
throw std::logic_error("unsupported type");
}
如果您没有C ++ 17,则可以使用boost::variant
代替std::variant
。
答案 1 :(得分:1)
我认为不是在枚举上决定向量的类型,而是更好的解决方案是让父class A
在其中有一个基于模板变量的向量。在您的班级B, C, D
中,您只需继承A
并指定模板类型即可。因此,当您为B, C, D
创建新对象时,您将拥有这些对象的矢量成员。您还可以使用虚拟函数convertToVec
,您可以在子类中覆盖它,具体取决于您希望如何将数据转换为矢量。
template<class T>
class A {
std::vector<T> vec;
std::vector<T> GetVector() { return vec; }
virtual convertToVec() { .... }
}
class B : public A<bool> {}
class C : public A<float> {}
class D : public A<long long int> {}
int main() {
B b;
b.GetVector();
//A* b = new B();
//b->convertToVec();
}
答案 2 :(得分:1)
虽然很难理解你在这里想要实现的目标,但是使用switch-case
并不是一个好主意,相反,你最好利用多态性。例如:
class A {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class B {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.convertToVectorB(this);
}
};
class C {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.doSomethingC(this);
}
};
// Aux class
class AuxVectorConverter {
public:
convertToVector(A* a) {
a->convertToVector(this);
}
convertToVectorB(B* b) {
// Do code specific for B
}
convertToVectorC(C* c) {
// Do code specific for B
}
}
int main() {
AuxVectorConverter* aux;
A* a = ...; // Initialize here either with instance of B or C
// Now, based on run time aux class will issue appropriate method.
aux.convertToVector(a);
}
您可以找到更多详细信息here
<小时/> 更新(基于评论)
另一种方法可以是定义从TYPES
到某个抽象类的映射,它将与上面的模式对齐,例如:
// Map has to be initialized with proper implementation
// of action according to type
map<Types, AbstracatAction> actions;
// Latter in the code you can do:
aux.convertToVector(actions[a->getType()]);
行动将被定义为非常类似于上面所示的等级,例如
class AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class ActionB: public AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) {
aux.covertToVectorB(this);
}
};