I have the following project structure:
This a handler for the "IOPin" class:
//IOPinHandler class
//IOPinHandler.h
#include <type_traits>
class IOPin; //forward declaration required
class IOPinHandler
{
public:
explicit IOPinHandler() { }
virtual ~IOPinHandler() { }
void checkBool(const bool& b);
void checkInt(const int& b);
template<typename T>
void modifyIOPinMember(IOPin& ioPin, const T& param);
};
//To avoid multiple definitions
#ifndef _OD_
void IOPinHandler::checkBool(const bool& b)
{
//Do stuff
}
void IOPinHandler::checkInt(const int& b)
{
//Do stuff
}
#endif
The following is the .tpp file for the definition of modifyIOPinMember member.
//IOPinHandler class
//IOPinHandler.tpp
template<typename T>
void IOPinHandler::modifyIOPinMember(IOPin& ioPin, const T& param)
{
if constexpr(std::is_same_v<T, int>)
{
checkInt(param);
ioPin.m2 = param;
}
else if constexpr(std::is_same_v<T, bool>)
{
checkBool(param);
ioPin.m1 = param;
}
}
The following is the "IOPin" class, the one meant to be handled by the class above. Since IOPinHandler's modifyIOPinMember member requires to know the definition of "IOPin" (its complete type) then, the IOPinHandler.tpp file is included in IOPin.h file as follows:
//IOPin class
//IOPin.h
//To avoid multiple definitions
#define _OD_
#include "IOPinHandler.h"
class IOPin
{
public:
explicit IOPin(const bool& b, const int& n):m1(b), m2(n) { _handler = new IOPinHandler; }
void setInt(const int& n) { _handler->modifyIOPinMember(*this, n); }
void setBool(const bool& b) { _handler->modifyIOPinMember(*this, b); }
private:
bool m1{false};
int m2{0};
IOPinHandler* _handler{nullptr};
friend class IOPinHandler;
};
#include "IOPinHandler.tpp"
The problem is that calling either setInt or SetBool methods, result in a compile time error:
//main.cpp
#include "IOPin.h"
IOPin a(false, 0);
int main()
{
a.setInt(89);
a.setBool(true);
return 0;
}
This is the error:
/usr/bin/ld: /tmp/ccpKv7HW.o: in function `void IOPinHandler::modifyIOPinMember<int>(IOPin&, int const&)':
main.cpp:(.text._ZN12IOPinHandler17modifyIOPinMemberIiEEvR5IOPinRKT_[_ZN12IOPinHandler17modifyIOPinMemberIiEEvR5IOPinRKT_]+0x27): undefined reference to `IOPinHandler::checkInt(int const&)'
/usr/bin/ld: /tmp/ccpKv7HW.o: in function `void IOPinHandler::modifyIOPinMember<bool>(IOPin&, bool const&)':
main.cpp:(.text._ZN12IOPinHandler17modifyIOPinMemberIbEEvR5IOPinRKT_[_ZN12IOPinHandler17modifyIOPinMemberIbEEvR5IOPinRKT_]+0x27): undefined reference to `IOPinHandler::checkBool(bool const&)'
collect2: error: ld returned 1 exit status
What am I missing over here?
I know that a solution is to create a "IOPinHandler.cpp" file and put there the definitions for "checkBool" and "checkInt" methods, however I dont want to have a separate .cpp file only for that.
Thanks in advance.