1. NTTP (C++98): Allows templates to accept non-type parameters like integers or pointers, enhancing flexibility and efficiency.
  2. CNTTP (C++20): Extends NTTP by using concepts to constrain non-type parameters, improving type safety and expressiveness.

Code Example

#include <concepts>
#include <cstddef>

// Function using NTTP  
template<size_t i>  // size_t is unsigned, so negative values will cause an error
auto get_value_nttp() { 
    return i;
}

// Function using CNTTP  
template<std::integral auto I> // constrained to integral types
auto get_value_cnttp() {
    return I;
}

int main() {
    // NTTP example
    auto x = get_value_nttp<10>();   // correct, 10 is a valid size_t
    // auto y = get_value_nttp<-10>();  // error, -10 is not a valid size_t (uncomment to see the error)

    // CNTTP example
    auto w = get_value_cnttp<10>();  // correct, 10 is an integral type
    auto z = get_value_cnttp<-10>(); // correct, -10 is an integral type
    return 0;
}