新版本的变更 / C++20

#include <concepts>
#include <iostream>
#include <string>
#include <type_traits>

// *** before: ***
// a requirement on a template argument was written with enable_if, and
// a wrong type gave pages of errors from deep inside the body
template <class T>
typename std::enable_if<std::is_integral<T>::valueT>::type doubledOld(
                          T value) {
    return value + value;
}

// *** in version C++20: ***
template <std::integral T>
T doubled(T value) { return value + value; }

// a concept of one's own: anything that can be sent to a stream
template <class T>
concept Printable = requires(const Tvaluestd::ostream& out) {
    { out << value } -std::same_as<std::ostream&>;
};

void show(const Printable autovalue) { std::cout << value << "\n"; }

// the same requirement in the long form
template <class T>
requires std::floating_point<T>
T half(T value) { return value / 2; }

int main() {
    std::cout << doubledOld(21) << " " << doubled(21) << "\n";
    // doubled(1.5);   <- error, and the message names the constraint itself
    show(42);
    show(std::string("text"));
    std::cout << half(3.0) << "\n";
}