Giriş
Şu satırı dahil ederiz.
Söz dizimi şöyle. Concept isminden sonra contraint ifadesi gelir.
1. concept X = std::type trait şeklinde tanımlanır. Type trait olarak std isim alanında milyon tane metod var.
Örnek
Şöyle yaparız
Concept sadece generic kodda foo() requires X şeklinde kullanılır.
Şu satırı dahil ederiz.
#include <concepts>
Açıklaması şöyle.
A Concept is basically a template parameter with constraints, e.g.C++20 ile geliyor. Eski kodlarda derleme esnasında hataları yakalamak için std::enable_if kullanırız. Yani şöyle yaparız. Yeni kodlarda concept kullanılır
template<typename T,
std::enable_if_t<has_less_than_op<T>::value, int> = 0>
const T& comp(const T& a , const T& b)
{return a<b?a:b;}
Concept Scope
Concept sınıf içinde tanımlanamaz. Şu kod derlenmez. Hata olarak şunu alırız. "error: concept declarations may only appear in global or namespace scope"
struct A
{
template <typename T>
concept foo = true;
};
Concept Tanımlama
concept-definition:
concept concept-name = constraint-expression ;
concept-name:
identifier
Constraint ifadesi iki şekilde tanımlanabilir.
1. concept X = std::type trait şeklinde tanımlanır. Type trait olarak std isim alanında milyon tane metod var.
Örnek
Şöyle yaparız
template<typename T>
concept MyClassIter = std::is_same_v<
MyClass,
typename std::iterator_traits<T>::value_type
>;
2. concept X = requires{...} şeklinde tanımlanır.Concept sadece generic kodda foo() requires X şeklinde kullanılır.
Örnek - generic olan ve olmayan kod
Generic olmayan kod derleme hatası verir. Görmek için şöyle yaparız
void f1(int a) requires true; // error: non-templated function
template<typename T>
auto f2(T a) -> bool requires true; // OK
Örnek
Şöyle yaparız
#include <iostream>
#include <vector>
template <typename T>
concept has_begin = requires(T t) {t.begin();};
int main(int argc, char *argv[])
{
std::cout << has_begin<std::vector<int>> << std::endl;
}
Concept Kullanarak std::enable_if'ten KurtulmakÖrneklerin çoğunu C++20 concept Kullanarak std::enable_if'ten Kurtulmak yazısına taşıdım.
Örnek
concept tanımı static_assert ile birlikte kullanılabilir. Elimizde şöyle bir kod olsun.
template<class T>
concept Valid = requires(T t) {
{ t.x };
};
struct ValidExample { int x; };
struct InValidExample {};
Şöyle yaparız.static_assert(Valid<ValidExample>); // ValidExample is Valid
static_assert(!Valid<InValidExample>); // InValidExample is not Valid
Örnekconstraint'i concept olmadan kullanmak hatalı olabilir. Şu kod hatalı.
template <typename T> inline constexpr bool C1 = true;
template <typename T> inline constexpr bool C2 = true;
template <typename T> requires C1<T> && C2<T>
constexpr int foo() { return 0; }
template <typename T> requires C1<T>
constexpr int foo() { return 1; }
constexpr int bar() {
return foo<int>();
}
Hiç yorum yok:
Yorum Gönder