If you claim to conform to an interface, it is not enough to follow the syntax, you must also be careful about the semantics.
I saw an example of this the other day, when I came across a custom vector class (different from std::vector
) used for numerics. It provided much of the same interface provided by std::vector
, among which, resize()
.
It looked something like this:
template <class T> class Vec { (...) //! STL vector interface void resize(int size, T value); }
That was however all the documentation that was available. Since it claimed to confirm to the stl::vector
interface, I naturally assumed it meant the same thing.
Here is the documentation for std::vector::resize(size_type sz, T c)
:
If
sz
is smaller than the current vector size, the content is reduced to its firstsz
elements, the rest being dropped.If
sz
is greater than the current vector size, the content is expanded by inserting at the end as many copies ofc
as needed to reach a size ofsz
elements.
Just to be sure, I had a look at the implementation of Vec::resize(int size, T value)
, and what do you know:
template <class T> //What was going on, conceptually: void Vec::resize(int size, T value) { _v.resize(0); _v.assign(size, value); }
See the difference? Vec::resize()
drops and initializes all elements, whereas vector::resize()
only initializes any extra elements. This might be dangerous if you for instance port from Vec
to vector
and rely on all elements to be reinitialized by resize()
, or if you port from vector
to Vec
and rely on resize()
to keep your old values.
So when claiming to confirm to an interface, make sure to not only adhere to the signature, but also to the semantics.