I have a home grown template class called Vec
which is a pale shadow of: std::vector<T>
To avoid re-inventing the wheel the header overloads for assign
are copied from: std::vector::assign
..so
As part of testing Str
class, ..test code is also run against std::vector<T>
to ensure equivalent output...
If std::vector<T>
is used then compiler will choose the correct overload:
However, when Vec<T>
is used then compiler insists on choosing the incorrect overload:
There is an obvious work around via casting the args to lvalues prior to use:
Question:
Given that both Vec<T>
and std::vector<T>
use identical header overloads for their respective assign
...how is std::vector<T>
able to implement rvalues arg without confusing the compiler?
[sequence.reqmts]/14 For every sequence container defined in this Clause and in Clause 21:
(14.2) — If the member functions of the forms:
template <class InputIterator> // such as insert() rt fx1(const_iterator p, InputIterator first, InputIterator last); template <class InputIterator> // such as append(), assign() rt fx2(InputIterator first, InputIterator last); template <class InputIterator> // such as replace() rt fx3(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);
are called with a type
InputIterator
that does not qualify as an input iterator, then these functions shall not participate in overload resolution.
This is typically implemented with a touch of SFINAE. You can check the headers of your favorite standard library implementation for details.