64

Are there any guidelines on how C++ templates and template meta-functions should be documented with Doxygen?

For example:

/// @brief metafunction for generation of a map of message types to
/// their associated callbacks.
/// @tparam Seq the list of message types
template< class Seq >
struct generate_callback_map
{
    typedef typename mpl::transform< Seq
                                   , build_type_signature_pair< mpl::_1 > 
                                   >::type vector_pair_type;
    typedef typename fusion::result_of::as_map< vector_pair_type >::type type;
};

So far I have seen the following suggestions:

  • @tparam used to document template parameters.
  • @arg alternative way of documenting template parameters.
  • @brief used to describe the metafunction.

How should the 'returned type' for the metafunction be documented?

Does anyone have any good suggestions or personal preferences for using Doxygen with C++ templates?

Null
  • 1,940
  • 9
  • 24
  • 29
mark
  • 6,939
  • 5
  • 34
  • 54
  • 4
    @Pubby: That's a really useful advice. What would you use, than? – Jan Hudec Nov 13 '12 at 10:46
  • @JanHudec Write it yourself rather than generating it. Use a style guide and consistent formatting of course. Readable code is a huge plus for TMP as they're a leaky abstraction. Explaining using a psuedocode helps as C++ syntax sucks. – Pubby Nov 13 '12 at 11:02
  • 5
    @Pubby must be kidding. Good docs is when you never look at the code. You read explanation comments in a header, and you don't even care to see at the implementation, that is, you don't care about a code style, formatting, readability and whatever more — this is a good docs. *Doxygen* is just a tool for extracting these docs from a source code *(ideally from headers)*. Of course if you want to distribute your API description like a bunch of «targzipped» headers instead of html/pdf/whatever, well, good luck; I'd prefer to use *Doxygen*. – Hi-Angel Feb 27 '15 at 06:44

2 Answers2

63

Use @tparam for template arguments, @arg for function arguments. For return values, @return. There is no return here. There are just typedefs.

BTW, your sample code doesn't look like a metafunction. Metafunctions are hairy beasts that take advantage of SFINAE to do something that C++ wasn't originally intended to do (e.g., reflection). Your generate_callback_map just looks like a C++03 stand-in for a template typedef.

What you are missing is documentation on your typedefs and documentation on how to use this template.

/// @brief metafunction for generation of a map of message types to
/// their associated callbacks.
/// @details
/// Usage: Use <tt>generate_callback_map<Type>::type</tt> to ...
/// @tparam Seq the list of message types
/// 
template< class Seq >
struct generate_callback_map
{
  /// @brief It's a good idea to document all of your typedefs.
  typedef typename mpl::transform< Seq
                                 , build_type_signature_pair< mpl::_1 > 
                                 >::type vector_pair_type;

  /// @brief This is why generate_callback_map exists. Document it!
  typedef typename fusion::result_of::as_map< vector_pair_type >::type type;
};
Mark Gates
  • 155
  • 1
  • 6
David Hammen
  • 30,597
  • 8
  • 54
  • 98
  • 9
    In C++, "metafunction" usually refers to a code such as the OP's. Yes, it's a typedef, but that typedef contains the type that is the result of evaluating the compile-time "function" specified. – jalf Nov 13 '12 at 11:31
  • 7
    I would dispute that there is no return here. Formally classes don't have return values, but logically the `type` typedef is a return. And would be better documented in the main documentation body for the class than as a separate member. – Jan Hudec Nov 13 '12 at 11:38
  • 2
    One could argue that there is a return here, in the same sense this this struct definition is a function. But from the point of view of Doxygen and related/compatible doc generators, trying to tag anything in the example with `@return` would just confuse it. @david's example typedef documentation serves this function and is unambiguous, but could be augmented by brief documentation on the struct itself. – Ionoclast Brigham Jan 21 '14 at 23:08
  • 1
    This actually should be selected as the right answer – Serg May 27 '14 at 12:15
  • link on documentation: https://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdtparam – Vlad May 07 '18 at 09:11
  • 3
    Most-recent link to `tparam` on Doxygen documentation: http://www.doxygen.nl/manual/commands.html#cmdtparam – Justin Time - Reinstate Monica Jun 13 '19 at 19:07
23

I don't think it is possible use document advanced template constructs with doxygen since it was originally designed for the object oriented paradigm and not metaprograming. As an illustration,GNU STL (libstdc++) uses doxygen but does a poor job of documenting metaprograming in the STL.

On the other hand, boost uses its own tools: QuickBook uses standalone text files and doxygen documented source to generate BoostBook markup (extension of DocBook) which in turns generates html/pdf. The result is more informative than for libstdc++ but obviously involves a little more work from the dev.

Since boost documentation is arguably one of the best for metaprograming you could go that route, especially since it complements doxygen - you can reuse your existing markup.

Although it does not exactly answer your question, you might be interested in recent clang developments. When building clang with --with-extra-options=-Wdocumentation it semantically checks your doxygen markup with your code and generates documentation warnings. Forces you to keep docs/code synchronized.

Antoine
  • 11,369
  • 6
  • 33
  • 47
  • 1
    I agree, the majority of boost documentation is very good and it certainly makes sense to follow their approach. – mark Nov 29 '12 at 14:34
  • 2
    Very good information here. The link to Clang/LLVM documentation checking is extremely useful! I had to use just `-Wdocumentation` to get it working. Doesn't strictly answer OP's question, though. – Ionoclast Brigham Jan 21 '14 at 22:58
  • 2
    Re "As an illustration,GNU STL (libstdc++) uses doxygen but does a poor job of documenting metaprograming in the STL." GNU does a poor job of documenting, period. Look at the source code. The little commentary that exists is at best poor. It's not fair to use GNU's lousy commentary as an example of the failures of doxygen. A better example would be some well-commented source that nonetheless comes out looking bad in doxygen. – David Hammen May 27 '14 at 13:08
  • @DavidHammen Indeed the example is not the best, but I struggle to find better examples: libraries well-documented in doxygen tend to be light on templates, and template-heavy libraries tend to use something other than doxygen. Suggestions welcome! – Antoine May 27 '14 at 17:24
  • 4
    @Antoine - Eigen, for one. Eigen is heavily templated. Their API is auto generated by doxygen. Does their API documentation stand on its own? Of course not. The API isn't enough for any software package of sufficient complexity. Think of the C++ standard library. Multiple books are needed to describe that library. Here's but one example of the Eigen source code: [Matrix.h, Eigen release 3.1](https://bitbucket.org/eigen/eigen/src/2afa6f331fdc61f3dee9ee0dd5b5d11123a665ce/Eigen/src/Core/Matrix.h?at=default). – David Hammen May 27 '14 at 18:57