递归模板参数
问题描述:
template <class T> class circuit{
private:
vector<T> components;
string type;
public:
complex<double> getImpedance();
};
complex<double> circuit<circuitComponent>::getImpedance() {
// function to calculate impedance in trivial case of components all in series/parallel
}
complex<double> circuit<circuit>::getImpedance() {}
我正试图编写一个程序,它能够计算任意电阻,电容和电感电路的(复数)阻抗。递归模板参数
对于一个电路,其中所有组件相互串联/并联,这是微不足道的。但是,这通常不正确。对于具有混合串联和并联元件的更复杂电路,我希望能够将电路描述为电路集合(即子电路/嵌套电路)。
所以,我想写一个电路类,可以包含一个向量组件,或一个电路矢量。我试图编写一个模板类来做到这一点,但是当我尝试为电路电路(我正计划以递归方式)的情况下定义getImpedance()函数时,我得到一个错误,因为编译器不会'不知道什么类型的子电路(即在电路中,内部电路没有已知类型)。
所以,我的问题是,有没有办法递归提供模板参数?
任何帮助将不胜感激。
请问
编辑:我的完整代码到目前为止是
#include<iostream>
#include<string>
#include<stdlib.h>
#include<cmath>
#include<vector>
#include <type_traits>
#include<complex>
using namespace std;
// Declare pi as const.
const double pi(3.1415927);
// A class for general circuit components.
class circuitComponent {
protected:
// The component type, its impedance, and the frequency of the AC current passing through it.
string componentType;
complex<double> impedance;
double frequency;
public:
circuitComponent(string compName, complex<double> imp, double freq) : componentType(compName), impedance(imp), frequency(freq) {}
virtual ~circuitComponent() {};
virtual void setImpedance(const complex<double>&) = 0;
// Functions to return the impedance and the frequency.
virtual complex<double> getImpedance() = 0;
virtual double getFrequency() = 0;
};
// A class for resistors, derived from circuitComponent.
class resistor : public circuitComponent{
protected:
double resistance;
public:
resistor() : circuitComponent("resistor",complex<double>(0,0), 0), resistance(0) {}
resistor(double res, double freq) : circuitComponent("resistor", complex<double>(res, 0), freq), resistance(res) {}
~resistor() {}
// A function to set the impedance of the component. Also alters the resistance accordingly.
void setImpedance(const complex<double>& imp){
// Deals with case of non-pure-real impedance assignment.
if (imp.imag() != 0){
cerr << "Cannot assign impedance with non-zero imaginary component to a resistor." << endl;
}
else {
resistance = imp.real(); impedance = resistance;
}
}
// Functions to return the impedace and the frequency of the resistance.
complex<double> getImpedance() { return impedance; }
double getFrequency() { return frequency; }
};
// A class for capacitors.
class capacitor : public circuitComponent{
private:
double capacitance;
public:
capacitor() : circuitComponent("capacitor", complex<double>(0, 0), 0), capacitance(0) {}
capacitor(double cap, double freq) : circuitComponent("capacitor", complex<double>(0, -1/(2.0*pi*frequency*cap)), freq), capacitance(cap) {}
~capacitor() {}
void setImpedance(const complex<double>& imp){
if (imp.real() != 0){
cerr << "Cannot assgn impedance with non-zero real component to a capacitor." << endl;
}
else{
impedance = imp; capacitance = imp.imag(); // THIS IS INCORRECT
}
}
complex<double> getImpedance() { return impedance; }
double getFrequency() { return frequency; }
};
// A class for inductors.
class inductor : public circuitComponent{
private:
double inductance;
public:
inductor() : circuitComponent("inductor", complex<double>(0, 0), 0), inductance(0) {}
inductor(double ind, double freq) : circuitComponent("inductor", complex<double>(0,2*pi*frequency*ind), freq), inductance(ind) {}
~inductor() {}
void setImpedance(const complex<double>& imp){
if (imp.real() != 0){
cerr << "Cannot assign impedance with non-zero real component to an inductor." << endl;
}
else{
impedance = imp; inductance = imp.imag(); // THIS IS INCORRECT
}
}
complex<double> getImpedance() { return impedance; }
double getFrequency() { return frequency; }
};
template <class T> class circuit{
private:
vector<T> components;
string type;
public:
complex<double> getImpedance();
};
// For the case where the circuit (or sub-circuit) has no subcircuits, and hence is a collection of components that are ALL in parallel/series with one another.
complex<double> circuit<circuitComponent>::getImpedance() {
complex<double> impedance(0);
vector<circuitComponent>::iterator componentIter;
if (type == "s"){
for (componentIter = components.begin(); componentIter != components.end(); ++componentIter){
impedance += componentIter->getImpedance();
}
}
else if (type == "p") {
complex<double> reciprocolImpedance(0);
for (componentIter = components.begin(); componentIter != components.end(); ++componentIter){
// complex<double>(1,0) is just the number 1 expressed as a complex number.
reciprocolImpedance += (complex<double>(1,0)/componentIter->getImpedance());
}
impedance = (complex<double>(1, 0))/reciprocolImpedance;
}
return impedance;
}
// THIS is the problem line.
complex<double> circuit<circuit>::getImpedance() {}
int main(){
string exitStr;
cin >> exitStr;
return 0;
}
答
你应该记住,circuit
是一个模板类;从而
complex<double> circuit<circuit>::getImpedance() {}
怎么一回事,因为(1)缺乏的template <>
和(2)内circuit
缺少模板参数之前,你可以不写东西。
写getImpedance
的方法是写一个通用版本,通过例如
template <typename T>
std::complex<double> circuit<T>::getImpedance()
{ return components.size() ? components[0].getImpedance() : 1.0; }
和circuitComponent
一个专门的版本,通过例如
template <>
std::complex<double> circuit<circuitComponent>::getImpedance()
{ return components.size() ? components[0].val : 0.0; }
一个完整的工作示例
#include <string>
#include <vector>
#include <complex>
#include <iostream>
struct circuitComponent
{ std::complex<double> val; };
template <typename T>
class circuit
{
private:
std::vector<T> components;
std::string type;
public:
std::complex<double> getImpedance();
};
template <>
std::complex<double> circuit<circuitComponent>::getImpedance()
{ return components.size() ? components[0].val : 0.0; }
template <typename T>
std::complex<double> circuit<T>::getImpedance()
{ return components.size() ? components[0].getImpedance() : 1.0; }
int main()
{
circuit<circuitComponent> c0;
std::cout << c0.getImpedance() << std::endl;
circuit<circuit<circuitComponent>> c1;
std::cout << c1.getImpedance() << std::endl;
}
+0
这是完美的,非常有帮助!非常感谢。 – willJG
你的问题不完整..请发布完整的代码...并且还描述了什么你想 – Arvindsinc2
阅读http://stackoverflow.com/help/mcve,并编辑你的问题 – Sniper