In a project I am working on, I am currently implementing an algorithm which is templated. I had some problems organizing my function declarations and definitions, because templates are involved (I asked a question here about how to deal with non-templated functions "grouped" together with the templated ones). This, however, made me wonder about a general proper organization of such files.
I wanted to separate all the definitions from all the declarations (just for readability purposes, even if I had to include templated definitions back into declarations).
The answers I got suggested organization such as this:
- The declarations file
algo.h
for all the function declarations - The templated definitions file
algo.tpp
which will be included inalgo.h
(templates need declarations at compile time) - The (non-templated) definitions file
algo.cpp
not included anywhere.
This works well if all the defined functions are supposed to be visible to the end-user (i.e. all the declarations are in the algo.h
file). However, sometimes I like to break my big functions into smaller functionalities, but I would like the end-user to be able to access only the "big function" and not their sub-parts. In a non-templated set-up, I would do this in this way:
- The declarations file
algo.h
would contain only the declarations meant for the end-user (which will become accessible through the include) - The definitions of those functions would go to
algo.cpp
- The definitions (and declarations) of the sub-functionalities would only be present in the
algo.cpp
, allowing my big function inalgo.cpp
(the one declared inalgo.h
) to use them, but not making them accessible to the end-user.
This does not work any more if those sub-functionalities are not themselves templated, but are used by the templated function. The templated sub-functionalities can go into the .tpp
file, get used by the templated "big function", and everything is good.
However, if those functionalities are non-templated, they would cause a multiple definitions error (which is what my previous question was about) if placed in the .tpp
file. On the other hand, if they are in the separate .cpp
file, they either become accessible to the end-user (if I put the declarations in the .h
file), or become inaccessible to the big function meant to use them (if I do not put the declarations outside the .cpp
file).
What is the proper way of organizing functions, some templated and some not, some of which are supposed to be accessible to the end-user, and some not, into multiple files?
Ideally, (for completeness), the answer I'm looking for would address the placement of the following (in the .h
, .tpp
, .cpp
, or other appropriate files):
- templated client functions
- non-templated client functions
- templated client functions
- non-templated client functions
- declarations of all of the above (when declarations are used)
Short almost-pseudo-code example of the functionality I want to have (without the file-separation)
// Templated sub-functionality, used by bigFunctionality,
// but ideally not accessible to the end-user
// This might not be possible since it is templated,
// so I am content with putting it in the .tpp file
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
// Non-templated sub-functionality, used by
// bigFunctionality, but NOT accessible to the end-user
void moreSubFunctionality(.. args ..) { /* impl */ }
// the main functionality, meant to be
// accessible to everybody across all files:
template <typename Compare>
void bigFunctionality( .. non-templated args ..., Compare order){
subFunctionality(order, .. args ..);
moreSubFun(.. args ..);
// more stuff
}
Once again, I am looking how to separate this in to multiple files (even if they are included in each other, as it has to be done with templates), partially for readability purposes and partially for accessibility.
Just for clarifications, these are algorithms --> functions, and not classes. (I know that putting templated and non-templated functions in to the same templated class would solve my problems).
PS: I know the title of the question is very big and long, so if somebody has an idea about shortening it, I would be more than happy for the suggestions/edits