Arm Mbed OS support forum

C++ question about templates

This is a question about C++ that I got while coding an mbed application. I’m no expert at C++ and I don’t even know what terms to search on google.

This is my situation:
I created a class (lets call it Decoder) that I need to pass a Mail object to its constructor and it stores the reference in a private variable.
Mail objects are created using Mail<type, size>, so for now I use the same type and size inside the class definition like this:

class Decoder {
    Decoder(Mail<SomeType, 32> &st) : _st(st) {}

private:
    Mail<SomeType, 32> &_st;
}

now I can use it like this:

Mail<SomeType, 32> st;
Decoder decoder(st);

But if I want to change the size the Mail then I get errors at compile:

Mail<SomeType, 64> st;
Decoder decoder(st); // Error

To fix it I would need to change the Decoder class.

Is there a way to avoid those changes in Decoder class?, make it accept Mail objects of SomeType and any size.

Hello Fabián,

You can try to define the Decoder as a templated class:

template<typename T, uint32_t queue_sz>
class Decoder {
public:
    Decoder(Mail<T, queue_sz>& st) : _st(st) {}

private:
    Mail<T, queue_sz>& _st;
};

Then create an instance of same type as Mail. For example:

Mail<uint8_t, 32>     st;
Decoder<uint8_t, 32>  decoder(st);

Best regards, Zoltan

Thanks Zoltan, yes that is better but I still have to write the size of the Mail in two locations, I would like to avoid that. I tried using a templated constructor and argument deduction but I could not figure how to declare the private _st Mail using argument deduction.

Another option is to use inheritance rather than composition. The Decoder becomes a Mail extended with additional functions. For example:

template<typename T, uint32_t queue_sz>
class Decoder : public Mail<T, queue_sz> {
public:
    Decoder() {}

    // Additional functions:

};

Then create an instance and you can use it also as a Mail:

Decoder<uint8_t, 32> decoder;  // a Mail with decoding features