jeudi 25 février 2016

Passing a pointer to a template class into the same template class's constructor

I have a set of classes I'm working on Term & Poly they are both class templates. Currently I am working with the Term class before I start to work on the Poly class. As it stands my class is working as expected. Here is its declaration and implementation and its instantiation.

Poly.h

#ifndef POLY_H
#define POLY_H

#include <iostream>

template<typename Coefficient, typename Exponent>
class Term {
private:
    Coefficient m_coefficient;
    char m_variable;
    Exponent m_exponentValue;
    Term<Coefficient, Exponent>* m_pExponentExpression;

public:
    Term();
    Term( Coefficient coefficient, char variable, 
          Exponent exponentValue = static_cast<Exponent>(1), 
          Term<Coefficient, Exponent>* pExponentExpression = nullptr );

    void display();
}; // Term

template<typename T>
class Poly {
    // TODO:
    // Empty Shell Class
}; // Poly    

#include "Poly.inl"

#endif // POLY_H

Poly.inl

template<typename Coefficient, typename Exponent>
Term<Coefficient, Exponent>::Term() :
m_coefficient( 0 ),
m_variable( ' ' ),
m_exponentValue( 0 ),
m_pExponentExpression( nullptr ) {
} // Term()

template<typename Coefficient, typename Exponent>
Term<Coefficient, Exponent>::Term( Coefficient coefficient, char variable, Exponent exponentValue, Term<Coefficient, Exponent>* pExponentExpression ) :
m_coefficient( coefficient ),
m_variable( variable ),
m_exponentValue( exponentValue ),
m_pExponentExpression( nullptr ) {
    if ( nullptr != pExponentExpression ) {
        // ExponentValue Will Equal One Since 1 Multiplied By Anything Equals Itself
        // 1 * (Expression) = Expression
        m_exponentValue = static_cast<Exponent>( 1 );
        m_pExponentExpression = pExponentExpression;
    } 

} // Term

template<typename Coefficient, typename Exponent>
void Term<Coefficient, Exponent>::display() {
    std::cout << m_coefficient;

    if ( nullptr == m_pExponentExpression ) {
        if ( m_exponentValue == static_cast<Exponent>( 1 ) ) {
            std::cout << m_variable; 
        } else {
            std::cout << m_variable << "^" << m_exponentValue;
            return;
        }
    }  else {
        std::cout << m_variable << "^(";
        m_pExponentExpression->display();
        std::cout << ")";
    }   
} // display

Poly.cpp

#include "Poly.h"

Here I demonstrate its use with a couple of template instantiations. I also demonstrate how the last two defaulted parameters for the constructor works and as it currently stands; if the pointer to a Term<> type is not null the exponent value passed into the constructor will default to 1. I may change this later, however with taking in the consideration of a case as such:

Term<int,int> expression( 2, 'x' ); // exponent = 1, expression = nullptr
Term<int,int> term( 4, 'x', 3, &expression );

// The reason for defaulting the third param '3' to '1' is this:
// Would the final term expression be 4x^(3+(2x)), 4x^(3(2x)) etc...

I may add more logic to this latter if I decide to parse in characters that are operators that belong to a term expression. Now for some of the uses of this class.

main.cpp

#include "Poly.h"

int main () {

    // Template Type <int,int>
    Term<int, int> termIIExpression1( 3, 'x', 2 );
    Term<int, int> termIIExpression2( 2, 'x', 1, &termIIExpression1 );
    Term<int, int> termII1( 5, 'y', 1, &termIIExpression2 );

    std::cout << "Using <int,int>" << std::endl;
    std::cout << "Term Expresion 1: ";
    termIIExpression1.display();
    std::cout << std::endl;

    std::cout << "Term Expression 2: ";
    termIIExpression2.display();
    std::cout << std::endl;

    std::cout << "Term 1: ";
    termII1.display();
    std::cout << std::endl << std::endl;

    // Template Type <double,int>
    Term<double,int> termDIExpression1( 2.8, 'y', 3, nullptr );
    Term<double,int> termDIExpression2( 4.2, 'y', 1, &termDIExpression1 );
    Term<double, int> termDI1( 3.14, 'y', 2, &termDIExpression2 );

    std::cout << "Using <double, int>" << std::endl;
    std::cout << "Term Expression 1: ";
    termDIExpression1.display();
    std::cout << std::endl;

    std::cout << "Term Expression 2: ";
    termDIExpression2.display();
    std::cout << std::endl;

    std::cout << "Term 1: ";
    termDI1.display();
    std::cout << std::endl << std::endl;

    return 0;
} // main

Now that you have seen this class in working use, my question becomes this: Considering that I am using a pointer to a term<typename, typename> type as my last parameter as another possible term within the exponent, how would I be able to do something like this:

main.cpp

#include "Poly.h"

int main() {

    Term<int, int> expression1( 3, 'x', 2 ); // 3x^2
    Term<double, int> term( 3.14, 'y', 1, &expression1 ); // 3.14y^(3x^2)

} // main

Without generating a compiler error where it can not deduce the template parameters from <int, int> to <double, int>? Meaning I would like the last parameter to be a pointer to any valid Term<typename, typename> type.

Aucun commentaire:

Enregistrer un commentaire