Mandatory template arguments

Consider the following function declaration:

Though the declaration may seem rather involved, the actual application of this function is quite simple:

The compiler knows how to create an instance of  print_as_csv by a mechanism called template argument deduction. It works only for functions, because the compiler needs arguments to deduce the types from. There are, however, template functions for which not all template arguments can be deduced by the compiler.

When template argument deduction fails

Think of make_unique, a sibling of  std::make_shared which we have presented in an earlier article. Its signature is repeated here:

The template parameter  Value of  make_unique cannot be determined by the arguments passed to it, so the user has to specify it herself. It is difficult to infer this information on a quick glance of the function’s signature. For each template argument we have to check whether it appears in the list of function arguents. Worse still, if one forgets to specify such template parameters, some compilers provide error messages of little help. For the line

g++ generates the following error message:

Although the message is technically correct, I know from own and repeated experience that a message in the line of “Dude, you forgot a template argument” might save some time. In general, we would like an easy way to highlight template arguments the compiler cannot deduce automatically and help the compiler to print a helpful error

Working around the compiler

To this end, we create a new header file, perhaps called mandatory.h to hold the following code:

The  static_assert  does the actual work of creating a legible error message. However, we need to make sure that we delay the evaluation of the condition to the last possible moment. If the condition in  static_assert would be just plain false or equivalent (such as std::is_same<double, int>::value), the compiler would terminate the compilation
immediately. For usability we provide the typedef  mandatory, which we use to modify the signature of make_unique:

Now it is clear from the signature that you need to specify Value yourself. If you forget to (just as in the example shown above), you get the following error message:

Of course, if you specify the mandatory template argument as intended, our feature stays perfectly invisible.

All in all, mandatory is a small helper class designed to work around bad compiler messages and make template function signatures an easier read.

Leave a Reply

Your email address will not be published. Required fields are marked *