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.
#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 metoduis_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 metodu
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.
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 metodu
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.
Checks whether T is an integral type. Provides the member constant value which is equal to true, if T is the type bool, 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.
std::true_type veya std::false_type olarak dispatch
edilir.
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 metodu
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.
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
Örnek ver
is_pointer metodu
Ö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>;
};
Örnek
Pointer 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 metodu
Constructor 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.
This is for backward compatibility with C.
Şöyle
yaparız.
#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 metodu
constructible 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 metodu
Açıklaması
şöyle.
Provides the member constant value that is equal to true, if T is the type void, const void, volatile void, or const volatile void.
has_virtual_destructor metodu
Örnek yaz
remove_reference metodu
Açıklaması
şöyle
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.
İmzası ve gerçekleştirimi şöyle
olabilir.
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