concepts are c++ language feature that make c++ template programming funny.
template <typename type_t20> concept always_true = true; template <always_true type_t00> class my_class { }; int main() { my_class<int> obj1; auto obj2 = my_class<char>{}; }
You see, always_true
is a concept, it is assigned
true.
c++ concept basic syntax:
template < typename the_constrait_type, typename other_type1, typename other_type2, ... ... ... > concept the_concept_name = the_constrait_expression ;
The concept template might have more than one template parameters, the first parameter is the target type to be constrained, the rest parameters are used to constrain the first parameter.
std::same_as constrains the target type (the first parameter) must be the same as the second type (the second parameter).
#include <concepts> template <std::same_as<int> type_t00> class test { }; int main() { test<int> t1{}; //test<const int> t2{}; // fail //test<unsigned int> t3{}; // fail //test<float> t4{}; // fail }
The std::same_as should be declared like this:
template <typename param1, typename param2> concept same_as = expression___ ;
The above example, template <std::same_as<int>
type_t00>,
type_t00 will be
passed as the first parameter: param1 ,
int will be passed as the second
parameter: param2 .
type_t00 is the target
constraint type.
std::integral requires the type must be an integral type.
#include <concepts> template <std::integral type_t00> class test { }; int main() { test<int> t0; // OK test<long int> t1; // OK test<unsigned int> t2; // OK // test<float> t3; // fail, float does not satisfy std::integral. }
std::floating_point requires the type must be a floating point type.
#include <concepts> template <std::floating_point type_t00> class test { }; int main() { auto t1 = test<float>{}; // OK auto t2 = test<double>{}; // OK //auto t3 = test<int>{}; // fail. int does not satisfy std::floating_point. }
Define concepts
c++ example
template <typename type_t20> concept has_int_get = requires (type_t20 value_ob) // requires { value_ob.get(); // It requires object of type_t20 has a method get() }; class tt_class { public: void get() { } }; template <has_int_get type_t00> class test { }; int main() { test<tt_class> t1{}; // OK: tt_class is a type that has a method get(). //test<int> t2{}; // fail. int does not have a method get(). }
The concept has_int_get requires the type has a method .get .
#include <concepts> template <typename type_t20> concept has_int_get = requires (type_t20 value_ob) // requires { // Requires the return type is the same as float. {value_ob.get()} -> std::same_as<float>; }; class tt_class { public: int get() {return 0;} }; class pp_class { public: float get() {return 1.2f;} }; template <has_int_get type_t00> class test { }; int main() { //auto t1 = test<tt_class>{}; // fail. tt_class::get does not return float. auto t2 = test<pp_class>{}; // OK }
The concept has_int_get requires the type must
have a method .get,
and that method must
return a type that is the same as float .
Although tt_class has a method get, but it returns int, not float .
pp_class has a method get, and it returns float .
So, tt_class does not satisfy
the concept has_int_get ,
pp_class
satisfies the concept has_int_get
.
Written on Nov 27, 2024
c++ std::exception:
std::cout.write(err.data(), err.size());
std::cout << std::endl;
caught:
=================================== # The c++ programming language. # # # # Join c++ Discord: yZcauUAUyC # # Deck # ===================================