0

I was writing some code for a project, and I was using a library named APA102. In this library, there is a class titled APA102 defined as follows,

template<uint8_t dataPin, uint8_t clockPin>
class APA102 : public APA102Base {
...

I am confused why anyone would use a template class to define a value that could have easily been passed as a class constructor parameter.

And to extend on my original question, I was attempting to create a class method that used this APA102 class as a parameter, but I was not able to define a parameter as this type if I tried to do as follows:

void someMethod(APA102<uint8_t, uint8_t> &param)

As I kept getting the error

error: type/value mismatch at argument 1 in template parameter list for 'template<unsigned char dataPin, unsigned char clockPin> class Pololu::APA102'
     virtual void someMethod(APA102<const uint8_t, const uint8_t> &ledStrip) = 0;

The only way I could have an APA102 object as a parameter was to define two uint8_t values, and use those as the template parameters first. For example, this worked:

const uint8_t clockPin = 11;
const uint8_t dataPin = 12;
virtual void someMethod(APA102<clockPin, dataPin> &ledStrip) = 0;

Can anyone help me understand these template classes with predefined template parameters? Why did I get the error I did?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Franklin V
  • 230
  • 1
  • 6
  • 1
    `void someMethod(APA102<11, 12> &param)` should also work – Jerry Jeremiah Jul 21 '20 at 03:04
  • 3
    If the value is fixed at compile time (i.e. the value is known when the object of that templated type is created, rather than depending on (say) user input), then there is no need to store the value in the object. In other words, your example (where you rightly got the error) is wrong - try `void someMethod(APA102<2,3> &param)`. That function will not accept being passed (say) an `APA102<3,4>` because the instantiated types are distinct. – Peter Jul 21 '20 at 03:06
  • 3
    The main reason to pass the values to the template instead of the constructor is because it is needed at compile time. See https://stackoverflow.com/questions/38270796/why-are-non-type-template-arguments-used and https://stackoverflow.com/questions/12550398/why-we-use-non-type-template-arguments – Jerry Jeremiah Jul 21 '20 at 03:07
  • 2
    The other useful thing you can do is typedef APA102<11, 12> to a name that means something to the reader and then you can use that new typename and no one has to wonder "what does that 11 and 12 mean again?" – Jerry Jeremiah Jul 21 '20 at 03:11
  • 2
    A good example of this in practice is to declare an array as a data member, where the class can be used with differently-sized arrays. Since arrays have a fixed size that must be known at compile time, using template parameters is a good way to provide that size. For example, see [`std::array`](https://en.cppreference.com/w/cpp/container/array), which does exactly the same thing. – cdhowie Jul 21 '20 at 03:23

0 Answers0