With the c++11 and c++14 library concepts, may a valid implementation of the c++ standard library create a specialized version of a function templated on a concept to take advantage of the additional functionality of child concept for optimizations that would not be possible with the base concept alone, such as with the InputIterator
constructor of std::vector
, and iterators which fulfill the requirements of RandomAccessIterator
?
// specified by standard
vector(InputIt begin, InputIt end, const Allocator& alloc = Allocator());
// is this specialization allowed in an implementation if it provides the same functionality?
vector(RandomAccessIt begin, RandomAccessIt end, const Allocator& alloc = Allocator());
Here, InputIt
is a type fulfilling the requirements of the InputIterator
concept, and RandomAccessIt
fulfills the requirements of RandomAccessIterator
. Notably, this concept lacks a requirement for finding the difference between two iterators, while its great-grandchild concept RandomAccessIterator
does require
It a,b;
It::difference_type c = a - b;
to be valid. Finding the difference between two iterators would be a help to the InputIterator
constructor for std::vector
in the cases where RandomAccessIterator
is also a concept fulfilled by the supplied iterators, since it would allow an implementation to pre-allocate the space required by the final vector, rather than resizing it multiple times during construction.
I can see it being valid, because of the Standard's occasional use of as-if rules, such as with covariant return types for virtual functions in inheritance hierarchies. However, there are rather distinct differences between the situations, so I can also see that the logic behind covariant return types may not necessarily have transferred to this situation.
To reiterate: may a valid implementation of the c++ standard library create a specialized version of a function templated on a concept to take advantage of the additional functionality of child concept for optimizations that would not be possible with the base concept alone?
Note: I've not tagged this question with c++-concepts because as far as I can tell that tag is for Concepts-Lite and the Concepts TS, and this question is about the library concepts in c++11 and c++14
There is no way to determine externally which constructor you have invoked with a given signature in C++.
So the exact details of the vector
signature can be varied under the as-if rule so long as all constructors that are specified can be invoked, the behavior you get at satisfies the documented features, and any constructor arguments that would not have been valid remain invalid (as external code can do SFINAE testing to determine if a given set of arguments would construct a std::vector
).
As noted by the OP and comments, many standard library implementations just use tag dispatching to forward to more-efficient more-specialized versions.
Of interest would be the answer outside of the context of a constructor, where you can detect functions having specific signatures (and not just compatibility), and you can distinguish between distinct functions. I do not know the answer here, but I am under the (unvalidated) impression that functions that do not match the exact signatures described in the standard actually occur in std
libraries sometimes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With