On Thu, 31 Jul 2014 10:54:59 -0700, Robert Ramey
Eric Niebler-4 wrote
On 07/29/2014 05:14 PM, Niall Douglas wrote:
I'm all for Concepts as in compiler enforced ones, and I'll add them to AFIO when and only when C++ gets them. But for documentation they don't help.
Wow, I couldn't disagree more. I can't imagine how the standard algorithms would be specified without the use of concepts like "RandomAccessIterator", for instance. Clustering requirements into meaningful abstractions and assigning them names makes it possible to document library interfaces without an explosion of verbosity and repetition.
+10
Usage of concepts is greatly:
a) misunderstood b) misunderestimated as to their value in design AND documentation d) The word "concepts" is a big contributor to the problem - substitute "type requirements" or "type constraints" for concepts.
-1 to the above term substitutions for concepts. Type requirements/type constrains are not concepts. The reason concepts are misunderstood is because they have not been well defined. FWIW, here's my take on how they should be defined: Concepts are sets of types whose membership are compile-time determinable. Precisely, a concept is any set expressible in the following form: { T | T is a type and p(T ...) } where p is a (n+1)-ary compile time computable boolean function (a function in the mathematical sense, not an actual C++ function). p is said to be (or to express) the type requirements or type constrains for its associated concept. (Note: just as a set membership predicate is not its set, a type requirement is not its concept. For example, the predicate "there exists a,b and a,b are integers and b != 0 and c = a/b" does not denote the set of rational numbers, the symbol Q does.) A type T is said to model a concept C if T is a member of C. In such a case we also say that "T is a C". A concept B is said to be a refinement of a concept A if B is a subset of A. Why use concepts? Because they are helpful in documenting generic code, especially template type parameter requirements. Examples: 1) DefaultConstructible := { T | T has the method "T()" defined and accessible. } // Requirements: // T is DefaultConstructible. template <typename T> struct FooBar { ... }; std::tuple<int> is DefaultConstructible, therefore FooBar< std::tuple<int> > is well formed. Mostafa