Home > Enterprise >  Arduino sketch with header and code file added with template methods. Caught between 'undefined
Arduino sketch with header and code file added with template methods. Caught between 'undefined

Time:02-22

I have a header file declaring a method, and a code file with the implementation. On compile, the compiler errors out with 'undefined reference to...'. If I copy the implementation of the method to the header, it then tells me the method is being redefined in the code file. Surely if it can find the method in the cpp file to call a duplicate, then it can use it. Since it can't be found, adding it to the header shouldn't cause a redefinition.

All headers are protected. In the code below, if I uncomment the header implementation, the method is redefined, if I leave it commented, the method is undefined. If I use only the header implementation, everything compiles fine but is bad architecture. The cpp file is being correctly copied to the output folder. Example code:

  • test.ino
  • math.h
  • math.cpp

test.ino

#include "math.h"

void setup() {
  int result = Math::Double((int)2);
}

void loop() {}

math.h

#ifndef MATH_H
#define MATH_H

namespace Math {
  template <typename U>
  U Double(U value);

//  template <typename U>
//  U Interpolate(U value) {
//    return value * 2;       ​
//  ​}

}

#endif

math.cpp

#include "math.h"

template <typename U>
U Math::Double(U value) {
  return value * 2;       ​
}

CodePudding user response:

You have a few C syntax errors in your code.

  1. Templates have to be declared and defined inside header files (there is rare syntax that provides an exception to this, but I won't discuss that here).
  2. You are missing parentheses before your 'loop' function definition.
  3. You are declaring your Double parameter with the name "value" but then attempting to use it with the name "result"

Here's the corrected code:

EDIT Changed this to separate template declarations/definitions. The original answer will be below the row of asterisks after this revised answer.

math.h

#ifndef MATH_H
#define MATH_H

namespace Math {
  template <typename U>
  U Double(U value);
}

#include "math_ipp.h"
#endif

math_ipp.h

#ifndef MATHIPP_H
#define MATHIPP_H
#include "math.h"

namespace Math {
  template <typename U>
  U Double(U value) {
    return value * 2;
  }
}

#endif

test.ino

#include "math.h"

void setup() {
  int result = Math::Double((int)2);
}

void loop() {}

********** ORIGINAL ANSWER BELOW math.h

#ifndef MATH_H
#define MATH_H

namespace Math {
  template <typename U>
  U Double(U value) {
    return value * 2;
  }
}

#endif

test.ino

#include "math.h"

void setup() {
  int result = Math::Double((int)2);
}

void loop() {}
  • Related