C++11 – Derleme zamanında tür belirleyiciler (type traits)

Basitçe derleme zamanında tür hakkında bilgi edinmemizi sağlarlar. Kullanımları oldukça basittir:

#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

class A
{
public:
~A(){cout << "~A()" << endl;}
A& operator=(const A&) { return *this; }
};

int main()
{
cout << boolalpha << endl;

cout << is_object<int>::value << endl;
cout << is_object<int&>::value << endl;
cout << is_object<A>::value << endl;
cout << is_object<A&>::value << endl;

cout << "-----------------------------" << endl;

struct B {};

enum class C {};

cout << is_class<A>::value << endl;
cout << is_class<B>::value << endl;
cout << is_class<C>::value << endl;
cout << is_class<int>::value << endl;

cout << "-----------------------------" << endl;

function<void()> f = [](){cout << "is function object move assignable ?" << endl;};

cout << is_move_assignable<B>::value << endl;
cout << is_move_assignable<C>::value << endl;
cout << is_move_assignable<decltype(f)>::value << endl;
cout << is_move_assignable<A>::value << endl;

}

Başka bir kullanım alanları ise şablon (template) fonksiyonları için bir nevi koşul veya kısıtlama getirmek için de kullanılırlar. Tipik olarak std::enable_if ile kullanılırlar, std::enable_if temel olarak SFINAE (Substitution failure is not an error) prensibine dayanır. Kısacası derleyici, şablon fonksiyon overloadlarını yazarken oluşan hatayı görmezden gelir ve diğer fonksiyonları yazmaya devam eder., Örneğin:

#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;

class A
{
public:

friend ostream &operator<<(ostream &os, const A&)
{
os << "class A" << endl;
}
};

template <class T>
typename enable_if<is_integral<T>::value, T>::type
println(T a)
{
cout << "if T is a integral type: " << a << endl;
};


template <class T>
typename enable_if<is_object<T>::value, T>::type
println(T &a)
{
cout << "if T is a object type: " << a << endl;
};

int main(int argc, char**argv)
{

A a;

println(5);
println(a);

return 0;
}

Örnekte görüldüğü üzere println fonksiyonu iki farklı şekilde şablonu üretiliyor. “enable_if::value, T>::type” ifadesi ile sadece istenen türlerle o fonksiyonun çağrılmasına olanak veriyor. is_object aslında derleme zamanında gelen türün nesne mi olup olmadığını test etmemizi sağlıyor. Böylelikle kullanıma göre derleme zamanında uygun şablon fonksiyonlar yazılacak.

type traitslerin aşağıdaki linkte bir listesini bulabilirsiniz:

http://en.cppreference.com/w/cpp/types