Separating declarations and Definitions


dixond
12-03-2013, 04:10 PM
Replied to a previous post and never heard a response so I thought I would try starting a new thread.

Bill,

I cannot put all of my code in single unit even with a major refactorization effort. I am using the adapt.h tool and I have two classes that require

#include "adapt.h"

which will not work for reasons previously discussed.

I would greatly appreciate further explanation of the following:

"If you really need to compile your two classes separately, then you'll need to edit the interp_1d.h file into separate declaration and definition files; then you can include the declaration file more than once, and compile the definition file along with your other files."

I am an intermediate level c++ programmer and was unsuccessful in trying to separate the definitions into a *.c file. The code compiled but I wound up with additional symbol issues we I ran my application. I found the following at cplusplus.com

"Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as its declaration. That means that we cannot separate the interface in a separate header file, and that we must include both interface and implementation in any file that uses the templates."

Being able to pass functors was extremely helpful, but I am starting to get the impression that I will need to change adapt.h significantly if I break up the definitions and declarations (that is, I will have to remove templating).

Is there any way to resolve this issue without making major changes to adapt.h? Can you provide an example of what your *.cpp and *.h would look like after splitting.

Thanks,

David

Saul Teukolsky
12-06-2013, 01:30 PM
Hi David,

Using templated functions with separate compilation is tricky. You will pay a price, one way or another.

One way to handle this in your example is to change Adapt into a templated class, not just a class containing templated functions:

template <class T>
struct Adapt {
...

and remove the template keywords inside the struct. You'll have to edit the implementations appropriately:

template <class T>
Adapt<T>::Adapt(Doub tol) : TOL(tol),terminate(true),out_of_tolerance(false)
...

and so on. Now when you invoke Adapt you have to explicitly put in the template type:

Adapt<Doub(const Doub)> s(0.0);
s.integrate(func,a,b)

if func is an ordinary function, or something like

Func func(appropriate arguments);
Adapt<Func> s(0.0);

if Func is a functor. You will be able to compile separately, but the code is awful.


Best,
Saul Teukolsky