Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal for a standard library implementation to specialize a function templated on a concept with a child concept?

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

like image 395
jaggedSpire Avatar asked Dec 09 '15 21:12

jaggedSpire


1 Answers

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.

like image 103
Yakk - Adam Nevraumont Avatar answered Oct 30 '22 07:10

Yakk - Adam Nevraumont