Visual Studio 2019 16.3 supporte les Concepts de C++20

Par:
fredericmazue

mer, 11/09/2019 - 14:44

Microsoft annonce que les Concepts du standard C++20 sont supportés pour la première fois dans Visual Studio 2019 16.3 Preview 2.

Ce support concerne à la fois le compilateur et la bibliothèque standard. En revanche les Concepts ne sont pas encore supportés par Intellisense. Microsoft précise que la fonctionnalité peut être activée par le mode /std:c++. Lorsque toutes les fonctionnalités de C++20 seront implémentées, un mode /std:c++20 sera fourni.

Les Concepts de C++ sont des prédicats permettant d'exprimer les attentes d'un algorithme générique sur des arguments de templates. Ils permettent de documenter formellement les contraintes sur les templates et de les faire appliquer par le compilateur. Les concepts permettent d'écrire un code plus concis et dont la compilation est plus rapide. Vous pouvez en apprendre plus sur les Concepts par exemple en lisant ce billet de Bjarne Strousrtup.

Microsoft donne cet exemple de code pour illustrer le support des Concepts dans Visual Studio 2019 16.3 Preview 2 :

#include <concepts>

// This concept tests whether 'T::type' is a valid type
template<typename T>
concept has_type_member = requires { typename T::type; };

struct S1 {};
struct S2 { using type = int; };

static_assert(!has_type_member<S1>);
static_assert(has_type_member<S2>);
// Currently, MSVC doesn't support requires-expressions everywhere; they only work in concept definitions and in requires-clauses

//template <class T> constexpr bool has_type_member_f(T) { return requires{ typename T::type; }; }
template <class T> constexpr bool has_type_member_f(T) { return has_type_member<T>; }

static_assert(!has_type_member_f(S1{}));
static_assert(has_type_member_f(S2{}));

// This concept tests whether 'T::value' is a valid expression which can be implicitly converted to bool
// 'std::convertible_to' is a concept defined in <concepts>
template<typename T>
concept has_bool_value_member = requires { { T::value } -> std::convertible_to<bool>; };

struct S3 {};
struct S4 { static constexpr bool value = true; };
struct S5 { static constexpr S3 value{}; };

static_assert(!has_bool_value_member<S3>);
static_assert(has_bool_value_member<S4>);
static_assert(!has_bool_value_member<S5>);

// The function is only a viable candidate if 'T::value' is a valid expression which can be implicitly converted to bool
template<has_bool_value_member T>
bool get_value()
{
  return T::value;
}

// This concept tests whether 't + u' is a valid expression
template<typename T, typename U>
concept can_add = requires(T t, U u) { t + u; };

// The function is only a viable candidate if 't + u' is a valid expression
template<typename T, typename U> requires can_add<T, U>
auto add(T t, U u)
{
  return t + u;
}

Microsoft travaille en ce moment au support de Range, qui fournit des composants permettant de traiter des plages d'éléments et qui a une relation étroite avec Concept.

Commentaires

Si C++ a des qualités indéniables, tenter d'y introduire des concepts déjà présents depuis longtemps dans les langages managés et notament C# qui est de loin le plus avancé en la matière, me parait un peu illusoire.

Le C++ est un très bon langage! Alors pitié Mr Strousrtup, ne tentez pas d'égaler le C# sur la généricitié, les fonctions lambda linq et toutes les belles avancés que nous a fait vivre ce langage.!
C++ n'est pas adapté à cela. D'autant que la syntaxe proposé est d'une complexité allucinante et est à des années lumière de celle du C#.