-1

I am designing something to do operatorations from an expression, so for example (3 + 5), the string would be read and the expression will be evaluted and returned. Now I got the correct output, my problem is that I implemented the stack in three different ways, linked list, Vector, and dynamic array, now they all have the same method names, push and pop respectivity just different implementation. Now I got a function for each of them so that I got:

void doVectorOp(V_H<int> value, V_H<char> op){//my personal vector class for stack
   //do something
}
void doDynamicOp(D_H<int> value, D_H<char> op){
   //do something
}
void doLinkedOp(SLL<int> value, SLL<char> op){
   //do something
}

Now the three functions have the exact same code and do the same thing, but with different class types, can I reduce all these functions into one. Something like:

void doOp(Generic class<int> value, Generic class<char> op){
   //do something
}

thanks, Yun Fei Chen

cigien
  • 57,834
  • 11
  • 73
  • 112
Yunfei Chen
  • 630
  • 1
  • 8
  • 20

1 Answers1

1

You can use template template parameters as in the following example. A description of the syntax can be found here.

template < typename T >
struct V_H 
{
    void push() { std::cout << "V_H push" << std::endl; }
    void pop() { std::cout << "V_H pop" << std::endl; }
};

template < typename T >
struct D_H 
{
    void push() { std::cout << "D_H push" << std::endl; }
    void pop() { std::cout << "D_H pop" << std::endl; }
};

template < typename T >
struct SLL 
{
    void push() { std::cout << "SLL push" << std::endl; }
    void pop() { std::cout << "SLL pop" << std::endl; }
};



template < typename VAR_TYPE, template<typename> typename CLASS_TYPE >
void doOp( CLASS_TYPE<VAR_TYPE>& value, CLASS_TYPE<VAR_TYPE>& op){
    value.pop();
    value.push();
}

int main()
{
    V_H<int> vh;
    D_H<float> dh;
    SLL<double> sll;

    doOp( vh, vh );
    doOp( dh, dh );
    doOp( sll, sll );
} 

But in C++20 you can write is much easier:

void doOp( auto& value, auto& op)
{
    value.pop();
    value.push();
}

But now you can pass nearly everything to your templated function ( it is templated simply by using the auto keyword ) which may result in hard to read errors. So, as C++20 is available, you can use `concepts' like:

void doOp( auto& value, auto& op)
    requires requires // duplicated requires keyword for ad hoc requierement
{
    value.push();
    value.pop();
}
{
    value.pop();
    value.push();
}

which simply tells the compiler, that your type you pass must have a pop() and a pull() method.

Klaus
  • 24,205
  • 7
  • 58
  • 113
  • What is the double requires doing?? And what is ad hoc requirement?? – Yunfei Chen Jul 08 '20 at 17:00
  • @YunfeiChen: https://en.cppreference.com/w/cpp/language/constraints. You should also find it yourself if you start searching the documents with your favorite web search engine :-) – Klaus Jul 13 '20 at 07:27