0

I have class Foo defined as such:

foo.h:

class Foo
{
public:
    Foo() {}
    ~Foo() {}

    double Compute1(const double& n) const;

    template<int Dim>
    double Compute2(const double& n) const;
};

foo.cpp:

double Foo::Compute1(const double& n) const
{
    return Compute2<3>(n);
}

template<int Dim>
double Foo::Compute2(const double& n) const
{
    return pow(n, Dim);
}

I think that Compute2 has been specialized with Dim=3 when it is called by Compute1. But when I called:

Foo comp;
double a = comp.Compute2<3>(10.0);

The compiler said that

undefined reference to `double Foo::Compute2<3>(double const&) const'

What am I wrong in this case?

kstn
  • 537
  • 4
  • 14
  • I think you need to have an `extern template double Foo::Compute2<3>(const double& n);` somewhere before the call so that the it doesn't attempt to instantiate it again – UnholySheep Nov 14 '22 at 21:36

1 Answers1

0

The reason is that the compiler needs to know the definition of the template function when it is used, not just when it is declared. When you declare a template function, the compiler just generates a "skeleton" of the function; it doesn't generate any actual code.

When you call a template function, the compiler needs to generate the actual code for that function. In order to do that, it needs to have the definition of the function, not just the declaration.

So, in your example, when you call Compute2 from Compute1, the compiler needs to have the definition of Compute2 in order to generate the code for it. However, the definition of Compute2 is in the foo.cpp file, not the foo.h file. So the compiler can't find it, and you get an error.

The solution

is to put the definition of the template function in the header file, not the source file. That way, when you call the function from another file, the compiler will have the definition and will be able to generate the code.
Igor
  • 474
  • 2
  • 10
  • Please flag/vote to close duplicates as duplicates instead of answering. Answering stops to automatic cleanup process from being able to run. – NathanOliver Nov 14 '22 at 21:38
  • @Igor, the definition of Compute2 has been recognized in Compute1 when it's called. – kstn Nov 14 '22 at 21:40