MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Restricțiile șabloanelor

Operatorul requires

Restricțiile pentru șabloane (atât pentru funcții, cât și pentru clase) permit limitarea setului de tipuri posibile care vor fi utilizate ca argumente ale șabloanelor. Adăugând restricții pentru parametrii șablonului, se rezolvă următoarele sarcini:

  • Din antetul șablonului este clar ce tipuri de argumente sunt permise și ce tipuri nu sunt permise
  • Șablonul este creat doar dacă argumentele șablonului satisfac toate restricțiile
  • Orice încălcare a restricțiilor șablonului va duce la un mesaj de eroare care va fi mult mai aproape de cauza principală a problemei, și anume încercarea de a folosi un șablon cu argumente incorecte

Începând cu standardul C++20, limbajul a introdus operatorul requires, care permite stabilirea de restricții pentru parametrii șabloanelor.

template <parametri> requires restricții
conținutul șablonului;

Restricțiile reprezintă expresii condiționale care returnează un rezultat de tip bool - dacă parametrul de tip satisface condiția, atunci se returnează true. Fiecare restricție impune una sau mai multe cerințe pentru unul sau mai mulți parametri ai șablonului.

De exemplu, să definim o funcție care poate aduna numere:

#include <iostream>
 
template <typename T> requires std::is_same<T, int>::value || std::is_same<T, double>::value
T sum(T a, T b) { return a + b; }
 
int main()
{
    std::cout << sum(3, 4) << std::endl;
    std::cout << sum(12.5, 4.3) << std::endl;
    //std::cout << sum(5l, 7l) << std::endl;
}

Aici, este definit un șablon de funcție sum, care primește valori de tipul T și returnează suma acestora tot ca valoare de tipul T. După cuvântul cheie requires, pentru parametrul `T este stabilită restricția:

std::is_same<T, int>::value || std::is_same<T, double>::value

Pentru a defini restricțiile, se folosește structura încorporată std::is_same din biblioteca standard C++. Această structură tipizează două tipuri. Variabila value a structurii returnează true dacă cele două tipuri sunt identice. Astfel, expresia std::is_same<T, int>::value va returna true dacă T este de tip int. Similar, stabilim o altă restricție pentru tipul T, folosind std::is_same<T, double>::value. Apoi, folosind operatorul ||, combinăm cele două restricții. Astfel, T poate fi fie int, fie double.

Ulterior, putem transmite funcției sum() valori de tipuri care satisfac aceste restricții:

std::cout << sum(3, 4) << std::endl;        // transmitem int
std::cout << sum(12.5, 4.3) << std::endl;   // transmitem double

Valori de alte tipuri nu le putem transmite. De exemplu, în exemplul de mai sus este comentată linia unde funcției sum() i se transmit valori de tip long:

//std::cout << sum(5l, 7l) << std::endl;  // long nu va funcționa

Dacă această linie este decommentată, compilatorul nu va compila programul și va afișa o eroare care ne va informa că au fost transmise tipuri incorecte pentru funcția sum.