Michel Keijzers
Michel Keijzers

Reputation: 15357

How to convert a template definition into a class

The following code works when used without C++ classes (Arduino code);

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiA);

This creates a variable midiA with the correct type. The macro definition is:

#define MIDI_CREATE_INSTANCE(Type, SerialPort, Name)                            \
    midi::MidiInterface<Type> Name((Type&)SerialPort);

However, I want to use this inside a class (to create a class variable midiA), but I cannot get it to work.

What I have now is:

class MidiHandler
{
    midi::MidiInterface<(HardwareSerial&) Serial1)> midiA;
}

However, I get the following error:

MidiHandler.h: 23:39: error: type\value mismatch at argument 1 in template parameter list for 'template<class SerialPort, class _Settings> class midi::MidiInterface
  midi*: MidiInterface<((HardwareSerial&)Serial1)> midiA

I think I might need to add the template to the class MidiHandler, also I wonder if I need to initialize it in the constructor.

Upvotes: 0

Views: 101

Answers (3)

Michel Keijzers
Michel Keijzers

Reputation: 15357

Answer as result of the accepted answer by Luis Guzman:

In header file:

midi::MidiInterface<HardwareSerial> midiA;
midi::MidiInterface<HardwareSerial> midiB;
midi::MidiInterface<HardwareSerial> midiC;

In constructor:

MidiHandler::MidiHandler()
: midiA(Serial1),
  midiB(Serial2),
  midiC(Serial3)

Upvotes: 0

Luis Guzman
Luis Guzman

Reputation: 1026

Disclaimer: I don't have an Arduino to compile and test this, but from the pure C++ point of view, I would declare the member in the class declaration and initialize it in the constructor. Like this:

class MidiHandler
{
public:
    MidiHandler(HardwareSerial& serial_port)
        : midiA(serial_port)
    { }

private:
    midi::MidiInterface<HardwareSerial> midiA;
};

Then, instantiate the class like this:

MidiHandler handler((HardwareSerial&) Serial1);

DETAIL:

The MidiHandler class has a member variable named midiA of type midi::MidiInterface<HardwareSerial>, which is a template with one template parameter (the Type parameter from the macro). HardwareSerial is used as the value for the template parameter.

The type midi::MidiInterface<HardwareSerial> has a constructor requiring one parameter of type HardwareSerial&. Therefore, MidiHandler::MidiHandler, the MidiHandler class constructor, needs a parameter of the same type to be used to construct midiA.

Finally, Serial1 is passed as the constructor parameter to handler. Serial1 must be of type HardwareSerial& or convertible to it. The C stile cast, (HardwareSerial&), may or may not be needed depending on the type of Serial1, but I put it there since the macro had it.

Upvotes: 1

Robert Andrzejuk
Robert Andrzejuk

Reputation: 5222

As is shown in the define:

#define MIDI_CREATE_INSTANCE(Type, SerialPort, Name) midi::MidiInterface<Type> Name((Type&)SerialPort);

So substituting in Your values should be:

midi::MidiInterface<HardwareSerial> midiA((HardwareSerial&)Serial1);

Upvotes: 1

Related Questions