In generic programming, a '''concept''' is a description of supported operations on a type, including syntax and semantics. In this way, concepts are related to abstract types but concepts do not require a subtype relationship.

==Language use== The term was in use as early as 1998 for STL,<ref>Austern, M.H. ''Generic programming and the STL: using and extending the C++ Standard Template Library''. 1998. pp 17–18</ref> as this was one of the first libraries that extensively used templates. The term ''concept'' (and its popularization) is credited to Alexander Stepanov,<ref>[https://isocpp.org/blog/2016/02/a-bit-of-background-for-concepts-and-cpp17-bjarne-stroustrup a bit of background for concepts and C++17—Bjarne Stroustrup], by Bjarne Stroustrup | Feb 26, 2016</ref><ref>[https://isocpp.org/blog/2016/01/alex-stepanov Alex Stepanov], by Bjarne Stroustrup | Jan 21, 2016</ref> the primary designer of the STL.

In the C++ 1998 standard, the ''Concept'' term was introduced to name just a simple description of the requirements for particular type, usually being a template parameter. It was not encoded in the language explicitly – the concept was expressed only by what operations are attempted on objects of that type and what is expected to work (that is, to compile correctly). There was a proposal to add concepts as an explicit language feature in C++11, though it was rejected as "not ready". C++20 eventually accepted the refined design of concept, though it was a reduced version of its former proposal.<ref>{{cite web |url=https://isocpp.org/blog/2013/02/concepts-lite-constraining-templates-with-predicates-andrew-sutton-bjarne-s |title=Concepts Lite: Constraining Templates with Predicates |date=2013-02-24 |publisher=isocpp.org |author=Andrew Sutton}}</ref> Concepts are an example of structural typing.

As generics in Java and C# have some similarities to C++'s templates, the role of concepts there is played by interfaces. However, there is one important difference between concepts and interfaces: when a template parameter is required to implement a particular interface, the matching type can only be a class that implements (explicitly) that interface. This is known as nominal typing. Concepts bring more flexibility because they can be satisfied in two ways: * explicitly defined as satisfied by using a concept map (defined separately to the type itself, unlike interfaces) * implicitly defined for "auto concepts", which can be used also for built in types and other types that were not predestined for this use

But the C# language has several constructs where the used type does not need to explicitly implement a defined interface, it is only required to match the respective pattern (however, these patterns are not called ''concepts''). E.g. the <code>foreach</code> iteration statement allows the iterated object to be of any type, as long as it implements an appropriate <code>GetEnumerator</code> method.<ref>[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#the-foreach-statement ''C# 6.0 draft specification'', ''The foreach statement'']</ref> (Compare with the <code>using</code> statement which requires the resource to implement the <code>System.IDisposable</code> interface.<ref>[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#the-using-statement ''C# 6.0 draft specification'', ''The using statement'']</ref>)

The Nim programming language implements concepts as a series of arbitrary compile-time boolean predicates.<ref>{{Cite web |title=Nim Experimental Features |url=https://nim-lang.org/docs/manual_experimental.html#concepts |access-date=2023-06-19 |website=nim-lang.org}}</ref>

Another language implementing something very similar to concepts is Haskell, where the feature is called type classes.

In the Go programming language, interfaces are the equivalent of concepts in C++, which define a set of method signatures. Unlike Java/C# interfaces where classes must declare that they implement the interface, types that satisfy these signatures implement the interface (implicitly).<ref>{{Cite web|title=A tour of Go - Interfaces|url=https://go.dev/tour/methods/9|publisher=The Go Authors|website=go.dev|access-date=5 May 2026|author=The Go Authors}}</ref>

==Examples==

=== Total ordering ===

The total ordering concept describes the semantics of the <code><</code> operator. A type is totally ordered when <code><</code> is a binary predicate and satisfies the following properties:<ref>{{cite book |last=Stepanov |first=Alexander |date=2009 |title=Elements of Programming |publisher=Addison-Wesley Professional |page=49 |isbn=9780321635372}}</ref><ref>[https://www.jmeiners.com/efficient-programming-with-components/06_min_max.html#Reviewing-Total-Orderings Total Orderings - Efficient Programming with Components]</ref> * anti-reflexive: <code>!(a < a)</code> for any value <code>a</code>. * transitive: If <code>a < b</code> and <code>b < c</code> then <code>a < c</code>. * anti-symmetric: If <code>a < b</code> then <code>!(b < a)</code>. * total: If <code>a != b</code> then <code>a < b</code> or <code>b < a</code>.

Many algorithms rely on these properties to function properly. For example the <code>min</code> function can be safely defined on totally ordered types:

<syntaxhighlight lang="cpp"> import std;

using std::totally_ordered;

template <totally_ordered T> nodiscard constexpr T min(T a, T b) noexcept { return (b < a) ? b : a; } </syntaxhighlight>

Or, instead of the concept in place of <code>typename</code>, a <code>requires</code> clause can be used. A <code>requires</code> clause is only necessary when the constraints are too complex to be described directly in the <code>typename</code> declaration. Trailing <code>requires</code> clauses can also be used.

<syntaxhighlight lang="cpp"> template <typename T> requires totally_ordered<T> nodiscard constexpr T min(T a, T b) noexcept { return (b < a) ? b : a; } </syntaxhighlight>

=== Iterator ===

If a type <code>Iter</code> satisfies the Trivial Iterator concept in C++, and <code>i</code> is of type <code>Iter</code>, the following are valid expressions with corresponding semantics:<ref>[http://www.martinbroadhurst.com/stl/trivial.html Trivial Iterator<!-- Bot generated title -->]</ref> * <code>Iter i</code> default construction. * <code>*i</code> must be convertible to some type <code>T</code>. * <code>i->m</code> is valid if <code>(*i).m</code> is.

==See also== * Protocol (object-oriented programming) * Concepts (C++) * Interface (Java) * Type class

== References == {{Reflist}}

==External links== * [http://www.boost.org/more/generic_programming.html Boost Generic Programming Techniques] * Douglas Gregor, et al. ''[http://www.research.att.com/~bs/oopsla06.pdf Concepts: Linguistic Support for Generic Programming in C++]'' * [https://www.youtube.com/watch?v=oZhixOWljWI Doug Gregor talk on Concepts at Google] (video) * [http://sms.cs.chalmers.se/publications/papers/2008-WGP.pdf A comparison of C++ concepts and Haskell type classes] {{Webarchive|url=https://web.archive.org/web/20170809215622/http://sms.cs.chalmers.se/publications/papers/2008-WGP.pdf |date=2017-08-09 }}

Category:Generic programming <!-- with 'class' not of the programming kind -->

ja:コンセプト (C++)