Unit-testing C++ templates - c++

I've used function and class templates in implementation of my libraries.
So far I've just instantiated a template in the library unit-tests (CppUnit),
and then proceeded to test it almost like any other normal class or function.
Recently I've been planning to add some templates also to the library APIs.
Good interface is of course the most important thing, template or not.
With well designed and implemented templates you can, if not totally prevent,
at least make it more difficult for the user to shoot himself in the foot.
Any way I feel that unit-testing public templates need to be a bit more rigorous,
compared to purely internal templates.
So, how have you unit-tested your C++ templates?
Have you come up with any elegant solutions,
especially for templates in public library APIs?

For starters, unit test your template code with the parameter you think is most likely for a user to supply. I've often made things templates "just in case" and end up never using anything but the one type I had in mind when I wrote the original code. So in that case, testing the most likely case covers all cases!
If you feel like you need to test more, use another template argument as different as possible from the first argument. It may not be necessary to test all methods again. Some methods may not actually depend on the template parameter.

I have an additional suggestion. In addition to unit-testing each template, examine techniques that will help constrain the potentially vast universe of template arguments that your library users might try to pass to your templates.
For example: say that you only test your templates using the type arguments "string" and "char". You do not have proof that other type arguments will be problematic for this particular template, but for one reason or another you "suspect" that other untested type args will be problematic.
In a case such as the above example, it doesn't necessarily imply that you should exhaustively test other type args. Instead, you have a case that might imply you should employ some compile-time template metaprogramming techniques to ensure that your template is never used with any other arguments but "string" and "char".
One resource:
Modern C++ Design -- by Andrei Alexandrescu
Very early on in this book, the author shows examples such as:
how to make a template that will self-enforce that its first type arg be of a smaller type than its second type arg
how to detect convertibility and inheritance at compile time
"Modern C++ Design" (despite its rather broad/vague title) is a fairly advanced exploration of template programming techniques.

Boost.Test has a component facilitating testing of templates against set of template parameters.

Instanciating the template in the unit test is the to test a template class.
What are the risks ? They depend what your library is doing with the template parameter ; think about what problems could arise depending on the class used to instanciate your template class and write new tests.
At least you will have your unit testing environment ready to reproduce any problem that will be reported.

Related

How does the compiler define the classes in type_traits?

In C++11 and later, the <type_traits> header contains many classes for type checking, such as std::is_empty, std::is_polymorphic, std::is_trivially_constructible and many others.
While we use these classes just like normal classes, I cannot figure out any way to possibly write the definition of these classes. No amount of SFINAE (even with C++14/17 rules) or other method seems to be able to tell if a class is polymorphic, empty, or satisfy other properties. An class that is empty still occupies a positive amount of space as the class must have a unique address.
How then, might compilers define such classes in C++? Or perhaps it is necessary for the compiler to be intrinsically aware of these class names and parse them specially?
Back in the olden days, when people were first fooling around with type traits, they wrote some really nasty template code in attempts to write portable code to detect certain properties. My take on this was that you had to put a drip-pan under your computer to catch the molten metal as the compiler overheated trying to compile this stuff. Steve Adamczyk, of Edison Design Group (provider of industrial-strength compiler frontends), had a more constructive take on the problem: instead of writing all this template code that takes enormous amounts of compiler time and often breaks them, ask me to provide a helper function.
When type traits were first formally introduced (in TR1, 2006), there were several traits that nobody knew how to implement portably. Since TR1 was supposed to be exclusively library additions, these couldn't count on compiler help, so their specifications allowed them to get an answer that was occasionally wrong, but they could be implemented in portable code.
Nowadays, those allowances have been removed; the library has to get the right answer. The compiler help for doing this isn't special knowledge of particular templates; it's a function call that tells you whether a particular class has a particular property. The compiler can recognize the name of the function, and provide an appropriate answer. This provides a lower-level toolkit that the traits templates can use, individually or in combination, to decide whether the class has the trait in question.

C++ should I use templates, I'm about to create a lexer, why should it be limited chars? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm about to create a lexer for a project, proof of concepts of it exists, the idea works and whatnot, I was about to start writing it and I realised:
Why chars?
(I'm moving away from C, I'm still fairly suspicious of the standard libraries, I felt it easier to deal in char* for offsets and such than learn about strings)
why not w_char or something, ints, or indeed any type (given it has some defined operations).
So should I use a template? So far it seems like yes I should but there are 2 counter-arguments I can consider:
Firstly, modular complication, the moment I write "template" it must go in a header file / be available with implementation to whatever uses it (it's not a matter of hiding source code I don't mind the having to show code part, it will be free (as in freedom) software) this means extra parsing and things like that.
My C background screams not to do this, I seem to want separate .o files, I understand why I can't by the way, I'm not asking for a way.
Separate object files speed up complication, because the make file (you tell it or have it use -MM with the compiler to figure out for itself) wont run the complication command for things that haven't changed and so forth.
Secondly, with templates, I know of no way to specify what a type must do, other than have the user realise when something fails (you know how Java has an extends keyword) I suspect that C++11 builds on this, as meta-programming is a large chapter in "The C++ programming language" 4th edition.
Are these reasons important these days? I learned with the following burned into my mind:
"You are not creating one huge code file that gets compiled, you create little ones that are linked" and templates seem to go against this.
I'm sure G++ parses very quickly, but it also optimises, if it spends a lot of time optimising one file, it'll re-do that optimisation every time it sees that in a translation unit, where as with separate object files, it does a bit (general optimisations) only once, and perhaps a bit more if you use LTO (link time optimisation)
Or I could create a class that every input to the lexer derives from and use that (generic programming I believe it's called) but my C-roots say "eww virtuals" and urge me towards the char*
I understand this is quite open, I just don't know where to draw the line between using a template, and not using a template.
Templates don't have to be in the header! If you have only a few instantiations, you can explicitly instantiate the class and function templates in suitable translation units. That is, a template would be split into three parts:
A header declaring the templates.
A header including the first and implementing the template but otherwise only included in the third set of files.
Source files including the headers in 2. and explicitly instantiating the templates with the corresponding types.
Users of these template would only include the header and never the implementation header. An example where this can be done are IOStreams: There are basically just two instantiations: one for char and one for wchar_t. Yes, you can instantiate the streams for other types but I doubt that anybody would do so (I'm sometimes questioning if anybody uses stream with a different character type than char but probably people are).
That said, the concepts used by templates are, indeed, not explicitly represented in the source and C++11 doesn't add any facilities to do so either. There were discussions on adding concepts to C++ but so far they are not part of any standard. There is a concepts light proposal which, I think, will be included in C++14.
However, in practice I haven't found that much of a problem: it is quite possible to document the concepts and use things like static_assert() to potentially produce nicer error messages. The problem is more that many concepts are actually more restrictive than the underlying algorithms and that the extra slack is sometimes quite useful.
Here is a brief and somewhat made-up example of how to implement and instantiate the template. The idea is to implement something like std::basic_ostream but merely provide out scaled-down version of a string output operator:
// simple-ostream.hpp
#include "simple-streambuf.hpp"
template <typename CT>
class simple_ostream {
simple_streambuf<CT>* d_sbuf;
public:
simple_ostream(simple_streambuf<CT>* sbuf);
simple_streambuf<CT>* rdbuf() { return this->d_sbuf; } // should be inline
};
template <typename CT>
simple_ostream<CT>& operator<< (simple_ostream<CT>&, CT const*);
Except for the rdbuf() member the above is merely a class definition with a few member declarations and a function declaration. The rdbuf() function is implemented directly to show that you can mix&match the visible implementation where performance is necessary with external implementation where decoupling is more important. The used class template simple_streambuf is thought to be similar to std::basic_streambuf and, at least, declared in the header "simple-streambuf.hpp".
// simple-ostream.tpp
// the implementation, only included to create explicit instantiations
#include "simple-ostream.hpp"
template <typename CT>
simple_ostream<CT>::simple_ostream(simple_streambuf<CT>* sbuf): d_sbuf(sbuf) {}
template <typename CT>
simple_ostream<CT>& operator<< (simple_ostream<CT>& out, CT const* str) {
for (; *str; ++str) {
out.rdbuf()->sputc(*str);
}
return out;
}
This implementation header is only included when explicitly instantiating the class and function templates. For example, to instantiations for char would look like this:
// simple-ostream-char.cpp
#include "simple-ostream.tpp"
// instantiate all class members for simple_ostream<char>:
template class simple_ostream<char>;
// instantiate the free-standing operator
template simple_ostream<char>& operator<< <char>(simple_ostream<char>&, char const*);
Any use of the simple_ostream<CT> would just include simple-ostream.hpp. For example:
// use-simple-ostream.cpp
#include "simple-ostream.hpp"
int main()
{
simple_streambuf<char> sbuf;
simple_ostream<char> out(&sbuf);
out << "hello, world\n";
}
Of course, to build an executable you will need both use-simple-ostream.o and simple-ostream-char.o but assuming the template instantiations are part of a library this isn't really adding any complexity. The only real headache is when a user wants to use the class template with unexpected instantiations, say, char16_t, but only char and wchar_t are provided: In this case the user would need to explicitly create the instantiations or, if necessary, include the implementation header.
In case you want to try the example out, below is a somewhat simple-minded and sloppy (because being header-only) implementation of simple-streambuf<CT>:
#ifndef INCLUDED_SIMPLE_STREAMBUF
#define INCLUDED_SIMPLE_STREAMBUF
#include <iostream>
template <typename CT> struct stream;
template <>
struct stream<char> {
static std::ostream& get() { return std::cout; }
};
template <>
struct stream<wchar_t> {
static std::wostream& get() { return std::wcout; }
};
template <typename CT>
struct simple_streambuf
{
void sputc(CT c) {
stream<CT>::get().rdbuf()->sputc(c);
}
};
#endif
Yes, it should be limited to chars. Why ? Because you're asking...
I have little experience with templates, but when I used templates the necessity arose naturally, I didn't need to try to use templates.
My 2 cents, FWIW.
1: Firstly, modular complication, the moment I write "template" it must go in a header file…
That's not a real argument. You have the ability to use C, C++, structs, classes, templates, classes with virtual functions, and all the other benefits of a multi paradigm language. You're not coerced to take an all-or-nothing approach with your designs, and you can mix and match these functionalities based on your design's needs. So you can use templates where they are an appropriate tool, and other constructs where templates are not ideal. It's hard to know when that will be, until after you have had experience using them all. Template/header-only libraries are popular, but one of the reasons the approach is used is that they simplify linking and the build process, and can reduce dependencies if designed well. If they are designed poorly, then yes, they can result in an explosion in compile times. That's not the language's fault -- it's the implementor's design.
Heck, you could even put your implementations behind C opaque types and use templates for everything, keeping the core template code visible to exactly one translation.
2: Secondly, with templates, I know of no way to specify what a type must do…
That is generally regarded as a feature. Instantiation can result in further instantiations which is capable of instantiating different implementations and specializations -- this is template meta programming domain. Often, all you really need to do is instantiate the implementation, which results in evaluation of the type and parameters. This -- simulation of "concepts" and interface verification -- can increase your build times, however. But furthermore, that may not be the best design because deferring instantiation is in many cases preferable.
If you just need to brute-force instantiate all your variants, one approach would be to create a separate translation which does just that -- you don't even need to link it to your library; add it to a unit test or some separate target. That way, you could validate instantiation and functionalities are correct without significant impact to your clients including/linking to the library.
Are these reasons important these days?
No. Build times are of course very important, but I think you just need to learn the right tool to use, and when and why some implementations must be abstracted (or put behind compilation firewalls) when/if you need fast builds and scalability for large projects. So yes, they are important, but a good design can strike a good balance between versatility and build times. Also remember that template metaprogramming is capable of moving a significant amount of program validation from runtime to compile time. So a hit on compile times does not have to be bad, because it can save you from a lot of runtime validations/issues.
I'm sure G++ parses very quickly, but it also optimises, if it spends a lot of time optimising one file, it'll re-do that optimisation every time it sees that in a translation unit…
Right; That redundancy can kill fast build times.
where as with separate object files, it does a bit (general optimisations) only once, and perhaps a bit more if you use LTO (link time optimisation) … Separate object files speed up complication, because the make file (you tell it or have it use -MM with the compiler to figure out for itself) wont run the complication command for things that haven't changed and so forth.
Not necessarily so. First, many object files produce a lot of demand on the linker. Second, it multiplies the work because you have more translations, so reducing object files is a good thing. This really depends on the structure of your libraries and dependencies. Some teams take the approach the opposite direction (I do quite regularly), and use an approach which produces few object files. This can make your builds many times faster with complex projects because you eliminate redundant work for the compiler and linker. For best results, you need a good understanding of the process and your dependencies. In large projects, translation/object reductions can result in builds which are many times faster. This is often referred to as a "Unity Build". Large Scale C++ Design by John Lakos is a great read on dependencies and C++ project structures, although it's rather dated at this point so you should not take every bit of advice at face value.
So the short answer is: Use the best tool for the problem at hand -- a good designer will use many available tools. You're far from exhausting the capabilities of the tools and build systems. A good understanding of these subjects will take years.

C++: Enforcing template type implements a method

I have a template class and I want to know if it is possible to enforce that the template class type implements a certain interface, in particular I want to enforce that the type overloads the operator= method. In Java I would write:
public class Tree<T implements IComparable>{
public Tree(Vector<T> x){...}
}
What is the alternative in C++?
Just write the code assuming that it does. If it doesn't, it will fail to compile when the user passes in the non-conforming type. There is no need for an explicit feature here. But why on earth would you ever need an interface like IComparable for this? Templates are duck typed.
But the template error might get nasty. You can use type traits and static assert to make this simpler. However, the Standard doesn't provide a trait like this, so you'd have to write one with SFINAE.
Short answer:
No; there is no language feature to do this.
Shotish Answer:
The affect you want can be achieved using SFINAE and static asserts (asserts that are evaluated at compile time). Unfortunately this is a non trivial processes and requires a good understanding of template meta programming.
Longish Answer:
The features was suggested for the new C++11 standard, but did not make it through the review process. Read more here http://en.wikipedia.org/wiki/Concepts_(C%2B%2B) . At the current meeting (Portland Oct/12-19) Herb Sutter was suggesting that we should try for a two phase release (a minor followed by a new feature release) and concepts would be included in the first minor release. Whether this proposal is accepted will be available after the meeting.

Good Practice for Templated Classes and Handling Unwanted Type Declarations

What is considered "good practice" in handling unwanted data types for templated classes?
Let's say we have a function in a templated class that does number multiplication, but the driver file for the class declares an instance of the class with Type string.
I've been given the argument that this is a "personal problem" for whoever's creating the driver file, and that all that needs to be done on your part is proper function prologues in the header/implementation files.
I'm wondering if there is a general practice used with templates regarding this issue. Do you check your Types in a class before handling them (I guess, to a certain extent that defeats the purpose of a template), or do you define behavior for specific types (though this also seems like a defeat of purpose)?
Or do you simply document your code correctly and let the programmer who uses your class take the precautions?
I'd generally use something like Boost/C++11 static_assert to assert the properties you want This will not only let you assure that it's numeric, but has things like is_signed and is_integer to assure more detail about the type, if you need/want to.

Synthesizing the interface of T required by a class template

template <typename T>
class A
{
// use the type parameter T in various ways here
}
Is there any way to automatically synthesize a workable class definition for T, as used by the template A? My expectation is a tool or a compiler trick that could generate the boiler plate code for the type parameter T, which I could tweak further to my needs.
I know if I wrote the class A, I could provide some hints to the "user" using boost concepts checks etc... But it's an unfamiliar code base where I didn't have the luxury of writing class A. So far I build the needed parameter class T manually, by reading the code for class A and with the able assistance from the compiler (with its terse messages).
Is there a better way?
If I understand you correctly, you are looking for a way to automatically generate a concept archetype for a given template class. Currently, this is not possible and maybe it never will be.
The main problem here is that it is very hard to say anything about the semantics of As code without any a priori knowledge of T. Dave Abrahams wrote a blog post not too long ago, where he showed that it is possible to to call an unconstrained function from code that is constrained by concepts and the compiler will still be able to perform the concept checks correctly.
But what you are asking for is a compiler that synthesizes concept checks out of thin air. I'm not much of a compiler person but I can't think of a way to make this possible with today's tools. Although it surely would be very cool if this became possible some day.