|But what happens after? People will want to define their own concepts (ugh that name).|
And what is bad in it? We already can overload operator+ to behave like assigment of result of binary ^ operator to right hand operand and decrementing left hand operand at the same time. We can create a fishnet of inheritance (created exclusively from diamond inheritance) and season it with obscure overloads and a bunch of gotos. And some people wants and actually do it. Concepts is a tool, like everything in C++ and it is up to programmer to responsibly use it.
|C is a razor-sharp tool, with which one can create an elegant and efficient program or a bloody mess. |
— Brian Kernigan
|Why it is our responsibility to write code such that the compiler can produce a meaningful error message?|
1) We are not writing the code if we are not creating our own concept
. We merely pointing to constraints on arguments:
template <typename T>
template <Container T>
Was the second line much longer than first?
Does second line gives more information what can and what cannot be passed here?
Also Concepts gives you possibility to choose more efficient overload depending on traits of argument: implement two sorting alghoritm: first with complexivity of n2 and using BidirectionalIterator and second n·log(n) using RandomAccessIterator. Containers which support Random access iterators will use faster algorithm and those who supports bidirectional iterator only will use slower one.
2) Concepts is similat to Interfaces but withoun need to explicitly state that we are supporting one (for example by inheriting from abstract base class like in Java or C++). That give a chance to built-in types to satisfy Concept requirement. Cannot let a pointer to array element to be passed to function requiring RandomAccessIterator otherwise.
3) Concets allows template author to tell not only what do argument lack (operator had wrong return type, expected xxx
) but why: Type should be Sortable
(That means it should have member functions begin() and end() or overloaded functions std::begin and std::end() which returns iterators, which have  operator, which returns reference to value of type contained inside container
). Programmer will know what function will expect and will inspect those areas instead of playing detective and trying to determine what caused that error.