Say I need a new type in my application, that consists of a std::vector<int>
extended by a single function. The straightforward way would be composition (due to limitations in inheritance of STL containers):
class A {
public:
A(std::vector<int> & vec) : vec_(vec) {}
int hash();
private:
std::vector<int> vec_
}
This requires the user to first construct a vector<int>
and a copy in the constructor, which is bad when we are going to handle a sizeable number of large vectors. One could, of course, write a pass-through to push_back()
, but this introduces mutable state, which I would like to avoid.
So it seems to me, that we can either avoid copies or keep A immutable, is this correct?
If so, the simplest (and efficiency-wise equivalent) way would be to use a typedef and free functions at namespace scope:
namespace N {
typedef std::vector<int> A;
int a_hash(const A & a);
}
This just feels wrong somehow, since extensions in the future will "pollute" the namespace. Also, calling a_hash(...)
on any vector<int>
is possible, which might lead to unexpected results (assuming that we impose constraints on A the user has to follow or that would otherwise be enforced in the first example)
My two questions are:
- how can one not sacrifice both immutability and efficiency when using the above class code?
- when does it make sense to use free functions as opposed to encapsulation in classes/structs?
Thank you!