模板参数的递归

时间:2017-03-31 18:16:27

标签: c++ templates recursion

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()函数时,我得到一个错误,因为编译器没有t知道给子电路的类型(即在电路中,内部电路没有已知的类型)。

所以,我的问题是,有没有办法递归提供模板参数?

非常感谢任何帮助。

威尔

编辑:到目前为止,我的完整代码是

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

1 个答案:

答案 0 :(得分:0)

你应该记住circuit是一个模板类;所以你不能写一些东西

complex<double> circuit<circuit>::getImpedance() {}

beacuse(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;
 }