unresolved external symbol error
-
Hello everyone. I'm looking for help to debug my Qt program (Console Application on Windows).
/********************************************************
This function is used to check whether the number passed in parameter is a perfect n-th power or not.
By default, n=2 (then checks if the number is a perfect square).
*******************************************************/
template<typename T>
bool Numbers::isPerfectPower(const T& number, const int &n)
{
if (number < 0 && n % 2 == 0)
return false;
T epsilon = std::numeric_limits<T>::epsilon();
T i = 0;
while (std::pow(i, n) <= number)
{
double result = std::pow(i, n);
if (std::fabs(result - number) < epsilon)
return true;
i += epsilon;
}
return false;
}In "Numbers.h", I wrote:
namespace Numbers
{
//...
template<typename T>
bool isPerfectPower(const T& number, const int &n=2);}
And in the main.cpp file:
#include <QCoreApplication>
#include "Numbers.h"
//...
using namespace Numbers;int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout<<"\n\t"<<isPerfectPower(16.0,2);return a.exec();
}
Problem, I have the compilation error:
main.obj:-1: error : LNK2019: unresolved external symbol "bool __cdecl Numbers::isPerfectPower<double>(double const &,int const &)" (??$isPerfectPower@N@Numbers@@YA_NAEBNAEBH@Z) referenced in main function
Thanks in advance. -
Hello everyone. I'm looking for help to debug my Qt program (Console Application on Windows).
/********************************************************
This function is used to check whether the number passed in parameter is a perfect n-th power or not.
By default, n=2 (then checks if the number is a perfect square).
*******************************************************/
template<typename T>
bool Numbers::isPerfectPower(const T& number, const int &n)
{
if (number < 0 && n % 2 == 0)
return false;
T epsilon = std::numeric_limits<T>::epsilon();
T i = 0;
while (std::pow(i, n) <= number)
{
double result = std::pow(i, n);
if (std::fabs(result - number) < epsilon)
return true;
i += epsilon;
}
return false;
}In "Numbers.h", I wrote:
namespace Numbers
{
//...
template<typename T>
bool isPerfectPower(const T& number, const int &n=2);}
And in the main.cpp file:
#include <QCoreApplication>
#include "Numbers.h"
//...
using namespace Numbers;int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout<<"\n\t"<<isPerfectPower(16.0,2);return a.exec();
}
Problem, I have the compilation error:
main.obj:-1: error : LNK2019: unresolved external symbol "bool __cdecl Numbers::isPerfectPower<double>(double const &,int const &)" (??$isPerfectPower@N@Numbers@@YA_NAEBNAEBH@Z) referenced in main function
Thanks in advance.@Bineere Templates are instantiated at the place of usage, so their body needs to be available there. The error says it can't find the specialization of your template for the double type. That's because compiler can't create it at the place of instantiation because you moved the body of the function to the cpp file.
In short template functions code should go all in the header file and not be split between h and cpp.
-
Hi @Bineere,
While defining (not just declaring) the template function in the header, as @Chris-Kawa suggested, is the easier, more generalised solution, if you do need / want to keep the implementation private, you can provide explicit instantiations within your Numbers translation unit by adding something like this to the end of your
Numbers.cppfile:template bool Numbers::isPerfectPower(const double &number, const int &n);But then you have to do this for all
typename Ttypes you want to support, eg:// Explicit template instantiations. template bool Numbers::isPerfectPower(const float &number, const int &n); template bool Numbers::isPerfectPower(const double &number, const int &n); template bool Numbers::isPerfectPower(const long double &number, const int &n);If you wanted to support integers, you'd have to add explicit instantiations for those too, but since you're using
std::numeric_limits<T>::epsilon(), I assume you're happy to only support floating point types for now.Cheers.
-
J JonB referenced this topic on