Giriş
C++11 ile gelen type_traits metodları meta programming için kullanılıyor. is_xxx() ve has_xxx() ile başlayan bir sürü metod var.
Nasıl Yazılır
is_container isimli kendi metodumuzu yazmak isteyelim. Eğer parametrenin iterator inner sınıfı varsa true dönsün isteyelim. Şöyle yaparız.
is_abstract metodu
Örnek ver
is_arithmetic metodu
is_arithmetic yazısına taşıdım
is_assignable metodu
Sağdaki parametrenin, soldakine atanıp atanamayacağını döner. Elimizde şöyle bir kalıtım olsun
Verilen container sınıfının iteratorünün bidirectional olup olmadığını şöyle kontrol ederiz.
static_assert(std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename C1::iterator>::iterator_category>::value, "");
is_const metodu
is_const yazısına taşıdım.
is_enum metodu
is_enum yazısına taşıdım.
is_function metodu
is_function yazısına taşıdım.
is_lvalue_reference metodu
Parametrenin l-value ya da r-value olduğunu belirtir. Şöyle bir kullanırız.
Açıklaması şöyle. Parametrenin bool, char, veya char tipin, short, int tipi gibi bir şey olup olmadığını döner. is_arithmetic'teki gibi float bu gruba dahil değildir.
constructible traits yazısına taşıdım.
is_nothrow_constructible metodu
constructible traits yazısına taşıdım.
is_pod metodu
Bu metod C++20 ile deprecate ediliyor. Açıklaması şöyle.
C++11 ile gelen type_traits metodları meta programming için kullanılıyor. is_xxx() ve has_xxx() ile başlayan bir sürü metod var.
Nasıl Yazılır
is_container isimli kendi metodumuzu yazmak isteyelim. Eğer parametrenin iterator inner sınıfı varsa true dönsün isteyelim. Şöyle yaparız.
#include <vector>
#include <string>
#include <iostream>
#include <type_traits>
template<typename ...>
using void_t=void;
template<typename T, class=void> struct is_container : std::false_type {};
template<typename T>
struct is_container<T, void_t<typename T::iterator>> : std::true_type {};
int main()
{
std::cout << is_container<int>::value << std::endl;
std::cout << is_container<std::vector<int>>::value << std::endl;
return 0;
}
is_abstract metodu
Örnek ver
is_arithmetic metodu
is_arithmetic yazısına taşıdım
is_assignable metodu
Sağdaki parametrenin, soldakine atanıp atanamayacağını döner. Elimizde şöyle bir kalıtım olsun
class X
{
};
class Y : public X
{
};
Y'ye point eden bir nesnenin X'e point eden bir değişkene atanabileceğini şöyle kontrol ederiz.std::is_assignable<X*&, Y*>::value
is_base_of metoduVerilen container sınıfının iteratorünün bidirectional olup olmadığını şöyle kontrol ederiz.
static_assert(std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename C1::iterator>::iterator_category>::value, "");
is_const metodu
is_const yazısına taşıdım.
is_enum metodu
is_enum yazısına taşıdım.
is_function metodu
is_function yazısına taşıdım.
is_lvalue_reference metodu
Parametrenin l-value ya da r-value olduğunu belirtir. Şöyle bir kullanırız.
template <typename T>
constexpr bool is_lvalue(T&&) {
return std::is_lvalue_reference<T>{};
}
Şöyle çağırırız.std::string a("Hello");
is_lvalue(std::string()); // false
is_lvalue(a); // true
is_integral metoduAçıklaması şöyle. Parametrenin bool, char, veya char tipin, short, int tipi gibi bir şey olup olmadığını döner. is_arithmetic'teki gibi float bu gruba dahil değildir.
std::true_type veya std::false_type olarak dispatch edilir.Checks whether T is an integral type. Provides the member constant value which is equal to true, if T is the typebool
,char
,char16_t
,char32_t
,wchar_t
,short
,int
,long
,long long
, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants. Otherwise, value is equal to false.
class OraclePreparedStatement
{
public:
template<typename T>
void bind_param(uint32_t col_index, T&& param)
{
bind_param_impl(col_index, std::forward<T>(param),
std::is_integral<std::remove_reference_t<T>>());
}
private:
template<typename T>
void bind_param_impl(uint32_t col_index, T&& param, std::true_type)
{
statement->setNumber(col_index, oracle::occi::Number(param));
}
template<typename T>
void bind_param_impl(uint32_t col_index, T&& param, std::false_type)
{
statement->setString(col_index, std::forward<T>(param));
}
OracleConnection::StatementWrapper statement;
};
is_move_constructible metoduconstructible traits yazısına taşıdım.
is_nothrow_constructible metodu
constructible traits yazısına taşıdım.
is_pod metodu
Bu metod C++20 ile deprecate ediliyor. Açıklaması şöyle.
Deprecating the notion of “plain old data” (POD). It has been replaced with two more nuanced categories of types, “trivial” and “standard-layout”. “POD” is equivalent to “trivial and standard layout”, but for many code patterns, a narrower restriction to just “trivial” or just “standard layout” is appropriate; to encourage such precision, the notion of “POD” was therefore deprecated. The library trait is_pod has also been deprecated correspondingly.
Bu metod yerine is_trivial() veya is_standard_layout() metodlarını kullanmak gerek.
is_polymorphic metodu
is_pointer metodu
Örnek
Sadece pointer tipleri kabul eden bir kod için şöyle yaparız.
Pointer olan ve olmayan parametreleri ayırmak için şöyle yaparız.
Constructor veya Copy Constructor yoksa true döner. Şöyle yaparız.
is_trivially_copyable metodu
std::is_trivially_copyable yazısına taşıdım.
is_trivially_destructible metodu
Destructor yoksa true döner. Elimizde şöyle bir struct olsun.
Örnek ver.
is_standard_layout metodu
Açıklaması şöyle.
constructible traits yazısına taşıdım.
is_unsigned metodu
bool için bile çalışır ve true döner.
Açıklaması şöyle.
Örnek yaz
remove_reference metodu
Açıklaması şöyle
Elimizde şöyle bir kod olsun
is_polymorphic metodu
Örnek ver
Örnek
Sadece pointer tipleri kabul eden bir kod için şöyle yaparız.
template <typename T> struct MyTemplate
{
static_assert(std::is_pointer<T>::value, "Expected a pointer");
// T = value_type*
using value_type = std::remove_pointer_t<T>;
};
ÖrnekPointer olan ve olmayan parametreleri ayırmak için şöyle yaparız.
template <class T>
void Foo(const T* x) {
std::cout << "I am the pointer overload" << std::endl;
}
template <class T>
typename std::enable_if<!std::is_pointer<T>::value>::type
Foo(const T& x) {
std::cout << "I am the reference overload" << std::endl;
}
is_trivial metoduConstructor veya Copy Constructor yoksa true döner. Şöyle yaparız.
std::is_trivial<std::atomic<int>>::value, "std::atomic<int> not trivial");
is_trivially_copyable metodu
std::is_trivially_copyable yazısına taşıdım.
is_trivially_destructible metodu
Destructor yoksa true döner. Elimizde şöyle bir struct olsun.
struct A {
public:
A(int a, int c): a_(a+c), c_(a-c) { }
A(const A& arg): a_(arg.a_), c_(arg.c_) { }
int a_;
char c_;
};
Şöyle yaparız.std::is_trivially_destructible<A>::value
is_signed metoduÖrnek ver.
is_standard_layout metodu
Açıklaması şöyle.
Şöyle yaparız.This is for backward compatibility with C.
#include <iostream>
#include <type_traits>
struct s_ref {
int &foo;
};
struct s_ptr {
int *foo;
};
int main(int argc, char *argv[])
{
std::is_standard_layout<struct s_ref>::value << std::endl; //false
std::is_standard_layout<struct s_ptr>::value << std::endl; //true
return 0;
}
is_trivially_constructable metoduconstructible traits yazısına taşıdım.
is_unsigned metodu
bool için bile çalışır ve true döner.
std::is_unsigned<bool>::value
is_void metoduAçıklaması şöyle.
has_virtual_destructor metoduProvides the member constant value that is equal to true, if T is the type void, const void, volatile void, or const volatile void.
Örnek yaz
remove_reference metodu
Açıklaması şöyle
İmzası ve gerçekleştirimi şöyle olabilir.If the type T is a reference type, provides the member typedef type which is the type referred to by T. Otherwise type is T.
template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};
Elimizde şöyle bir kod olsun
template <typename T>
typename remove_reference<T>::type Magic(T t) {
return t;
}
Bu kodu şöyle çağırırsak şu sonuçları alırız.Magic(int i) -> int i
Magic(int& i) -> int i
Magic(int&& i) -> int i
Hiç yorum yok:
Yorum Gönder