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:

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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s