2017-03-31 11 views
0
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()関数を定義しようとすると、サブ回路にどのタイプを与えるかを知っています(つまり、回路内の内部回路には既知のタイプがありません)。

私の質問は、再帰的にテンプレート引数を提供する方法はありますか?

ご協力いただければ幸いです。

ウィル

EDIT:私の完全なコードこれまであなたがcircuitは、テンプレートクラスであることを覚えておいてください

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

あなたの質問は不完全です..完全なコードを投稿してください...あなたは欲しい – Arvindsinc2

+0

http://stackoverflow.com/help/mcveを読んで質問を編集してください – Sniper

答えて

0

です。及び(2)の内側circuitでテンプレートパラメータの欠けている前

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

beacuseは、(1)template <>の欠けているように、あなたが何かを書き込むことはできません。

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

circuitComponentに特化したバージョンで、一般的なバージョンを書くことです

#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

関連する問題