BEFORE YOU READ: const_reference
is typedef and does not need to be const T&
as you can see in std::vector<bool>::const_reference = bool
. Please keep that in mind while reading the rest to understand it properly (as suggested in commets, this is hard for many people).
I wanted to use STL containers for simple types (e.g. int
) and found that they use the sub-optimal const T&
"anti-pattern" - it works well for big classes, but is sub-optimal for simple/fundamental types when not inlined - consider embedded system, e.g. on ARM/ATSAM4L, with instantiation.
The question is: why was e.g. vector::push_back
redesigned with argument of (const value_type&)
instead of (Allocator::const_reference
) since C++11?
It should be the same for generic allocator
, but doing it the other way would help me to write a custom allocator (or template specialization) for fundamental types that would define const_reference
being the type itself (see vector<bool>::const_reference = bool
).
Question 2: Is there any adaptor class that can do that for me?
Something like this:
template<class T, class base = std::vector<T> >
class myvect: protected base {
public:
typedef T const_reference;
void push_back(const_reference value) {
base::push_back(value); }}
Final usage would by like this:
typedef void (*action_t)(void*,int);
extern "C" void work(void *, action_t);
work(&vect, (action_t)&vect::push_back);
(note: ignore possible casting problems in previous code block, I hope you got the idea.)
EDIT: vector::const_reference
is defined directly to be const value_type&
but should in my opinion be defined as Alloc::const_reference
which could then easily be changed (vector<int, MyAllocator<int> >
). (This changed in C++11, it was defined as Alloc::const_reference but is now const value_type&)
EDIT: func(const T&)
is sometimes described as "anti-pattern" here on stackoverflow because it is sub-optimal for fundamental types without inlining (yes, compiler generates optimal code even for func(const int&)
if it gets inlined, but here is that IF. func(int)
will do better work)
CONCLUSION: The very problem seems to be in the behaviour of const
and therefore const T&
. const
does not really mean shall not change but do not change and therefore const T&
is needed (and well defined and used) as return type for many methods. Creating custom adaptor class seems to be the best way for optimization and it seems to be widely accepted, that std::vector<bool>
is odd exception which should be in separate class (e.g. dynamic_bitset
).