简体   繁体   中英

How do I declare non-const argumets to an object template

I did two classes, The first is template class Bit<size> that convert decimal number to a binary. The second is LogicalExpression class.

Bit class:

template<int size>
class Bit
{
public:
    Bit(int);
    void ConvertToBinary(int);
    bool number[size];
    int bit;
};

template <int size> Bit<size>::Bit(int decimalNumber)
{
    this->bit = 0;
    ConvertToBinary(decimalNumber);
}

template <int size> void Bit<size>::ConvertToBinary(int decimalNumber)
{
    number[size - ++this->bit] = decimalNumber % 2;
    if (size != this->bit) {
        ConvertToBinary(decimalNumber / 2);
    }
}

LogicalExpression class:

#include "Bit.h"
class LogicalExpression
{
private:
    char* expression;
    char* variables;
    int expLenght;
    int varLenght;

public:
    LogicalExpression(char*);
    ~LogicalExpression();
    bool ExpressionToBoolean(char*, Bit<????>); //here is the problem

I want to use the LogicalExpression class as a normal non-template class, as a result I do not know how to declare const argument for Bit<???> , it should be Bit<varLenght> , but varLenght is non-const value and i do not want to do LogicalExpression<varLenght> obj . Hope that my English not so bad, for not understanding me.

The problem here is possibly a misunderstanding of how templates work.

Templates are evaluated at compile time. Therefore the value inbetween < > can not contain a non-const . Its simply not possible because templates are not evaluated at run time . This is actually a strength, not a weakness (see TMP ). For comparison they are more like pre-processor defines then say a function call but they are actually not the same thing as macros

In this case you need to rethink your design. in this part:

 template<int size>
class Bit
{
public:
    Bit(int);
    void ConvertToBinary(int);
    bool number[size];
    int bit;
};

You either want "number" to be a dynamic array so that it would either become something like:

class Bit
{
public:
    Bit(int length){ number = new bool[length]; } ;
    ~Bit(){delete number;}
    void ConvertToBinary(int);
    bool* number;
    int bit;
};

it doesn't need to be a template and would be used like:

bool ExpressionToBoolean(char*)
{
    Bit foo(varLength); 
}

You could use std::vector for simplicity.

OR "LogicalExpression" should be a template class (which you have said you don't want)

 template<int varLenght>
class LogicalExpression
{
private:
    char* expression;
    char* variables;
    int expLenght;

public:
    LogicalExpression(char*);
    ~LogicalExpression();
    bool ExpressionToBoolean(char*, Bit<varLenght>); //here is the problem

But really this boils down to a question of where you want your memory allocated , do you want it on the heap or the stack?

  • Heap : Dynamic array (can be evaluated at run time)
  • stack : Templates (can not be evaluated at run time)

If you don't care, i would probably just stick with the dynamic array approach because you could easily over complicate the problem with templates...but this problem may be suited to TMP based on your requirements. If you want it on stack then you will have to use some form of

LogicalExpression< "const" > obj

"somewhere", which if its a syntactical taste you could use something like:

   typedef LogicalExpresion8Bit LogicalExpression<8>

If you want dynamic evaluation then you have to either use dynamic memory or something a bit crazier like a combination of polymorphic and interfaces which will most likely lead to more memory on the stack then you actually want/need, not to mention a lot more code...(ie each variant stored in an array and selected via index).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM