Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ constraints enable_if vs requires

I just ran along the C++ requires keyword and want to know whether my understanding is correct so far: Both requires and enable_if offer compile time constraints for templates. If require constraints will be included at all.

Where requires offers a way of constraining function parameters, enable_if has the main purpose of restricting compile time translation to certain conditions of the template type itself.

Examples:

#include <type_traits>

template<typename T>
concept T AdditiveGroup
{
  return requires(const T pA, const T pB)
  {
    { pA + pB }->T;
  };
};

template<typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
addElements(const T pA, const T pB)
{ 
  return (pA + pB);
}

Here the concept should work if and only if pA and pB can be added, whereas the enable_if condition restricts evaluation to integral types.

Thanks for letting me know if I got this right!

P.S.: I am not yet quite sure at all about the syntax of the require constraints, which seems to vary. In addition, no idea which compiler accepts them at the time being, so thanks for any hints!

like image 989
gilgamash Avatar asked May 19 '16 06:05

gilgamash


1 Answers

Yes, your understanding seems to be correct. Using SFINAE to constrain templates (e.g. enable_if) has the same essential effect of concept-constrained templates. However (as you alluded to), SFINAE has additional side-effects.

Ville's Jacksonville paper about his rationale for including concepts in C++17 does an excellent job of explaining the pitfalls of SFINAE-based constraints when compared to concepts. Essentially:

  • Concepts allow constraining function arguments without turning off deduction and without disturbing the meta-arity of a constrained function template.
  • Concepts make it much easier to write overloads with mutually exclusive constraints.
  • Concepts enable a broad range of constraint designs, giving the interface designer various tools to decide what sort of abstractions a particular interface needs.
like image 164
blelbach Avatar answered Sep 30 '22 13:09

blelbach