I am trying to write a series of classes under a namespace titled numc
using the C++17 compiler. Currently I am working on a root solver class and for some reason when I define the functions in the header file the code works just fine; however, when I define the functions in the .cpp file, the code fails on compilation with the error clang: error: linker command failed with exit code 1
If I define the .hpp file like so with the .cpp file shown it works fine.
// Working main.cpp file
double upper = 3.0;
double lower = 0.0;
double guess = 2.0;
double right_side = 0.0;
double result;
result = numc::RootSolver::bisect(upper, lower, right_side, guess, func1);
double func1(double x)
{
return pow(x, 6.0) - x - 1.0;
}
// Working numc.hpp file
namespace numc
{
class RootSolver
{
public:
static double
bisect(double upper, double lower, double right_side,
double guess, const std::function<double(double)>& func,
double uncertainty = 0.001, int iter = 150);
private:
[[noreturn]] static void exit_program(int iter);
}
// ================================================================
// ================================================================
double
RootSolver::bisect(double upper, double lower, double right_side,
double guess, const std::function<double(double)>& func
double uncertainty, int iter)
{
for (int i = 0; i < iter; i++)
{
if (func(guess) - right_side <= unc and
func(guess) - right_side >= -unc) return guess;
else if (func(guess) - right_side > unc)
{
upper = guess;
}
else lower = guess;
guess = lower + (upper - lower) / 2.0;
}
RootSolver::exit_program(iter);
}
// ================================================================
// ================================================================
[[noreturn]] void
RootSolver::exit_program(int iter)
{
std::string one("Function did not converge within ");
std::string two(" iterations");
std::cout << one << iter << two << std::endl;
exit (EXIT_FAILURE);
}
}
When define in the manner shown above the program works just fine and produces a result of 1.3477. However, as you can see, instead of just defining the function prototypes in the .hpp file, I also defined the functions, which is bad form. The functions should be defined in the numc.cpp file.
If I take the working .hpp
file shown above and rewrite it as such and place the function definition in the .cpp
file I arrive at the following code.
// numc.hpp code
namespace numc
{
class RootSolver
{
public:
static double
bisect(double upper, double lower, double right_side,
double guess, const std::function<double(double)>& func,
double uncertainty = 0.001, int iter = 150);
private:
[[noreturn]] static void exit_program(int iter);
}
}
and the numc.cpp
code
#include "numc.hpp"
double
numc::RootSolver::bisect(double upper, double lower,
double right_side, double guess,
const std::function<double(double)>& func,
double unc, int iter)
{
for (int i = 0; i < iter; i++)
{
if (func(guess) - right_side <= unc and
func(guess) - right_side >= -unc) return guess;
else if (func(guess) - right_side > unc)
{
upper = guess;
}
else lower = guess;
guess = lower + (upper - lower) / 2.0;
}
numc::RootSolver::exit_program(iter);
}
// ================================================================
// RootSolver PRIVATE MEMBER-FUNCTIONS
[[noreturn]] void
numc::RootSolver::exit_program(int iter)
{
std::string one("Function did not converge within ");
std::string two(" iterations");
std::cout << one << iter << two << std::endl;
exit (EXIT_FAILURE);
}
I have tried several variations, but no matter how I do it, when I place the member function definitions in the .numc.cpp
file, the code fails on compilation and tells me that I have a linker issue. If anyone can point out my mistake I would greatly appreciate it.