2

I have a template class ServoLink whose header file is in "/include" and whose source file is in "/src." The CMakeLists.txt file is in the project directory, in which the "include" and "src" folders reside. I started off declaring and defining all the functions in the header file, but I quickly realized my mistake, and I am trying to transfer the function definitions over to the source file. However, CLion tells me in the source file that none of the member variables of the class can be resolved.

The following is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.6)
project(Two_Link_Leg)

set(CCMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror -Wextra -pedantic -pedantic-errors")

include_directories("lib/Adafruit_PWMServoDriver")
include_directories(include)

set(SOURCE_FILES main.cpp src/ServoLink.cpp)
add_executable(Two_Link_Leg ${SOURCE_FILES})

ServoLink.h:

#ifndef TWO_LINK_LEG_SERVOLINK_H
#define TWO_LINK_LEG_SERVOLINK_H

#include <map>
#include "Adafruit_PWMServoDriver.h"

template <class size_t>
class ServoLink{

private:

    //servo motor channel number on the PWM/Servo driver; [0, 15]
    size_t mChannel;

    //pointer to a map of the servo motor's angular position with its corresponding pulse width value
    std::map<int, size_t>*  mPWM;

    //variable given by Adafruit
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

public:

    ServoLink(size_t givenChannel, size_t givenPWM[]);
};

#include "../src/ServoLink.cpp"

#endif //TWO_LINK_LEG_SERVOLINK_H

ServoLink.cpp:

#include <stdexcept>
#include <map>

template<typename size_t size>
ServoLink<size_t>::ServoLink(size_t givenChannel, size_t givenPWM[]):mChannel(givenChannel){
    mPWM= new std::map<int, size_t>;
    for(size_t i= 0; i< size; i++){
        mPWM->insert(std::make_pair(-90+((double)180*i/size), givenPWM[i]));
    }
}

If there is any syntactical error in my template code or a mistake in the CMakeLists.txt, I would appreciate any help in identifying them. Thank you.

BusyProgrammer
  • 2,783
  • 5
  • 18
  • 31
Skipher
  • 205
  • 4
  • 13
  • You forgot to include `ServoLink.h` into `ServoLink.cpp`. That is why you get the error about unknown type or wharever. – Tsyvarev Mar 18 '17 at 20:30

1 Answers1

1

There are a number of problems in your code. First, the structural part. There's no need to split out the constructor implementation to a separate .cpp file, you can include it in the header too if you want. If you put the implementation of the constructor right there inside the class definition in the header, it will be fine. If you put the implementation outside of the class definition, you probably want to mark it as inline, but it should still compile without that.

You don't need to (and in fact will get an error if you do) specify the .cpp file as one of the sources given to add_executable() in your CMakeLists.txt file. The compiler will see the inlined implementation of the template and be happy with that. No need to explicitly try to compile the template in this case.

Now to the code errors. The template parameters for the class definition are not correct. They should be:

template<size_t size>
class ServoLink {
    ...
};

You also need to #include <cstddef> to ensure size_t is a known type. What this says is that size is a template argument of type size_t, whereas your original code was trying to define a template argument whose name was size_t.

If you want to define the constructor implementation outside of the class definition, you would need to do so like this:

template<size_t size> inline
ServoLink<size>::ServoLink(size_t givenChannel, size_t givenPWM[]) ...

The inline is optional, but may silence warnings with some compilers about multiple definitions if you included the header in multiple .cpp files. See this answer for more info on that aspect. The template argument is of type size_t and has the name size. You then put the template argument name after the class name here.

With these changes (and making up a trivial main.cpp plus commenting out references to the Adafruit_PWMServoDriver header and class), the code compiles for me.

Community
  • 1
  • 1
Craig Scott
  • 9,238
  • 5
  • 56
  • 85