Dean Brundage
Dean Brundage

Reputation: 2048

error: no matching function for call to Counter::Counter()

I'm getting this error when I try to compile an Arduino sketch. I don't see where it thinks I'm trying to call Counter::Counter without arguments. What's going on here?

sketch/periodic_effect.cpp: In constructor 'PeriodicEffect::PeriodicEffect(uint32_t, uint32_t, Counter::Mode)':
periodic_effect.cpp:4: error: no matching function for call to 'Counter::Counter()'
 PeriodicEffect::PeriodicEffect( uint32_t durationMs, uint32_t periods, Counter::Mode mode) : Runnable(), periods(periods) {

periodic_effect.cpp

#include <Arduino.h>
#include "periodic_effect.h"

PeriodicEffect::PeriodicEffect( uint32_t durationMs, uint32_t periods, Counter::Mode mode) : Runnable(), periods(periods) {
  intervalMs = durationMs / periods;
  index = Counter(intervalMs, mode);
}


void PeriodicEffect::run() {
  uint32_t currTimeMs = millis();
  if( (currTimeMs - prevTimeMs) > intervalMs ) {
    applyChange();
    prevTimeMs = currTimeMs;
    index.increment();
  }
}

periodic_effect.h

#ifndef PERIODIC_EFFECT_H
#define PERIODIC_EFFECT_H

#include "counter.h"
#include "runnable.h"

class PeriodicEffect : public Runnable {

  public:
    PeriodicEffect( uint32_t durationMs, uint32_t periods, Counter::Mode mode = Counter::Mode::RESETTING );

    Counter index;

  private:
    uint32_t intervalMs, periods, prevTimeMs;

    virtual void applyChange() = 0;
    void run();
    virtual void setup() = 0;
};

#endif

counter.h

#ifndef COUNTER_H
#define COUNTER_H

#include <stdint.h>


class Counter {
  public:
    enum Mode { RESETTING, RETURNING };
    Counter(uint32_t limit, Counter::Mode mode = RESETTING, uint32_t index = 0);

    uint32_t getIndex();
    void increment();
    float percent();

  private:
    bool goingForward;
    uint32_t index;
    const uint32_t limit;
    Counter::Mode mode;

    void incrementReturning();
    void incrementResetting();

};

#endif

counter.cpp

#include "counter.h"

Counter::Counter(uint32_t limit, Counter::Mode mode, uint32_t index) : index(index), limit(limit), mode(mode) {
  goingForward = true;
}


uint32_t Counter::getIndex() {
  return index;
}


void Counter::increment() {
  switch( mode ) {
    case RESETTING : incrementResetting();
    case RETURNING : incrementReturning();
  }
}


void Counter::incrementResetting() {
  index = (index + 1) % limit;
}


void Counter::incrementReturning() {
  if( goingForward ) {
    index++;
    if( index >= limit ) {
      index = limit - 1;
      goingForward = false;
    }
  } else {
    index--;
    if( index <= 0 ) {
      index = 1;
      goingForward = true;
    }
  }
}


float Counter::percent() {
  return (float) index / (float) limit;
}

Upvotes: 3

Views: 220

Answers (2)

aschepler
aschepler

Reputation: 72271

PeriodicEffect::PeriodicEffect(
    uint32_t durationMs, uint32_t periods, Counter::Mode mode) :
    Runnable(), periods(periods) { /* ... */

PeriodicEffect has a member Counter index;. Since index is not in the member initializer list of this constructor, it gets default constructed.

The statement

index = Counter(intervalMs, mode);

inside the constructor is an assignment, not an initialization. Too late.

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308121

Your class PeriodicEffect has a Counter member variable, and no constructor. This means the member variable will need to be default constructed, i.e. constructed by a constructor with no parameters. You haven't supplied one.

You can either give Counter a default constructor, or let the existing constructor have defaults for all of the parameters. Or you can make a PeriodicEffect constructor with an initializer list to provide the proper parameters to index.

Upvotes: 4

Related Questions