Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are constrained templates?

Tags:

c++

c++14

Herb Sutters mentioned constrained templates (a.k.a. Concepts Lite) in the talk: Modern C++: What You Need to Know.

I know that boost has a concepts package in for ages, that allows one to pretty print error messages, when template deduction mechanism fails to find operators, functions or has access violation patterns.

I've encountered mentions on the isocpp blog that there is already an experimental branch of gcc implementing the document proposing Concepts Lite. However looking through the current C++14 draft I couldn't find any hints whether this will be already part of C++14.

So the questions are simple:

  • will Concepts Lite be part of C++14? (Reference in the standard preferred. I could not find one, and I'm not very familiar with the standard.)
  • what is the correct syntax of it? (The proposal and the slides of Herb diverge here and I don't know which one is more up to date)
  • could you give a minimal example of a constraint (predicate) and a constrained template?

NOTE: if you wait long enough I'll try to get the gcc branch running and can at least say anything about the experimental implementation, which however does not imply the correctness of the syntax.

like image 1000
Alexander Oh Avatar asked Apr 04 '14 21:04

Alexander Oh


People also ask

What is a constraint template?

ConstraintTemplates define a way to validate some set of Kubernetes objects in Gatekeeper's Kubernetes admission controller. They are made of two main elements: Rego code that defines a policy violation. The schema of the accompanying Constraint object, which represents an instantiation of a ConstraintTemplate.

What are constraints C++?

A constraint is a requirement that types used as type arguments must satisfy. For example, a constraint might be that the type argument must implement a certain interface or inherit from a specific class. Constraints are optional; not specifying a constraint on a parameter is equivalent to using a Object constraint.

What is constraint in C programming?

According to the C Standard, 3.8 [ISO/IEC 9899:2011], a constraint is a "restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted." Despite the similarity of the terms, a runtime constraint is not a kind of constraint.

What is C++ trait?

Traits in C++ is like std::numeric_limits or std::iterator_traits . It takes a type and returns some information about that type. The default implementation handles a certain number of cases, and you can specialize it to handle other cases.


1 Answers

Concepts Lite is the "constraints" part of a full concepts design for C++. It is described in great detail in N3701 "Concepts Lite". Chapter 2 is a short tutorial that quickly runs through the core principles and their application, which is great for folks that don't want to read through all 56 pages.

Concepts Lite will not be part of C++14, it will be released as a separate Technical Specification later this year. The latest rough draft for the TS wording is N3929 "Concepts Lite Specification".

There are a few different constraint syntax variants. The code example that Herb used in the talk:

auto mean(const Sequence& seq) {
  auto n = 0.0;
  for (auto x : seq)
    n += x;
  return n / seq.size();
}

is referred to as the "terse syntax" since it's a shorter equivalent of the verbose syntax:

template <typename __T>
  requires Sequence<__T>()
auto mean(const __T& seq) {
  auto n = 0.0;
  for (auto x : seq)
    n += x;
  return n / seq.size();
}

They both indicate that the function template mean can be instantiated with any type that models the Sequence concept. For the sake of simplicity, lets assume that the requirements for Sequence are only what our implementation of mean needs: (a) members begin & end that return iterators, and (b) member function size that returns some integral type. We could define the concept as:

template <typename T>
concept bool Sequence() {
  return requires(T t) {
    {t.size()} -> Integral;
    {t.begin()} -> InputIterator;
    {t.end()} -> InputIterator;
    requires Same<decltype(t.begin()), decltype(t.end())>();
  }
}

assuming straight-forward definitions of Integral, InputIterator, and Same. This concept definition ensures that, for some invented value t of the type T being tested:

  • t.size() is a valid expression, and it returns a type that models the Integral concept.
  • t.begin() is valid, and returns a type that models InputIterator.
  • Same for t.end().
  • The InputIterator returned by t.begin() has the same type as that returned by t.end().
like image 71
Casey Avatar answered Oct 03 '22 08:10

Casey