30 Eylül 2015 Çarşamba

Stream İle Parsing Yöntemleri

1. Line Oriented Yöntem
Bence en kolay yöntem. Stream veya dosya satır satır okunur. Her satır tek başına işlenir.

Sınıf Okumak
Elimizde şöyle satırlar olsun. Her değer sınıfın bir alanıdır.
M Tyler 1234567890 3 soccer football tv Jess
F Lyns 1234567890 3 hockey sex movies
F Jess 1234567890 3 soccer football tv Tyler
M Taylor 1234567890 3 hockey sex movies
Sınıfımız da şöyle olsun.
struct person
{
    string Sex;
    string Name;
    string Match; //optional alan, satırın en sonunda
    int phoneNumber;
    int numInterests;
    vector<string> interests;
};
 Hiç hata kontrolü olmayan iskelet kod şöyledir.
void LoadClients(std::ifstream &myFile,vector<person>& peps)  
{  
    person p;  
    string line;  
    while( getline( myFile, line ) )  
    {  
        istringstream iss( line );  
        iss >> p.Sex >> p.Name >> p.phoneNumber >> p.numInterests;  
        for(int i=0;i<p.numInterests;i++){  
            string interest;  
            iss >> interest;  
            p.interests.push_back(interest);  
        }  
        iss >> p.Match;
    }  
}; 
Şimdi satırda hata olduğunu varsayalım. Bu durumda iss için hata kontrolü eklememiz gerekirdi. Şöyle yaparız.
string line;
while( getline( myFile, line ) )
{
    istringstream iss( line );

    // Now, parse out of 'iss' instead of 'file'.
    person p;
    bool ok = false;
    if( iss >> p.Sex >> p.Name >> p.phoneNumber >> p.numInterests )
    {
        p.interests.reserve( p.numInterests );
        for( int i = 0; i < p.numInterests; i++ )
        {
            string interest;
            if( iss >> interest ) p.interests.emplace_back( interest );
        }

        ok = !iss.error();

        iss >> p.Match; // optional
    }

    if( ok ) peps.push_back( p );
}

2. Field Oriented Yöntem
Satırların önemi yoktur. Alanlar boşluk veya başka bir ayraç ile ayrılmıştır.
Elimizde şöyle bir dosya olsun

192, 16 120, 134 256, 87 122, 167 142, 97 157, 130 245, 232 223, 63 107, 217 36, 63 206, 179 246, 8 91, 178
Okumak için şöyle yaparız.
std::map<int, int> mymap;

char dummy;
int a, b;
while (myFile >> a >> dummy >> b)
{
   mymap[a] = b;
}
Eğer bir alan hatalıysa şöyle atlarız. Elimizde şöyle bir dosya olsun
2.4 4.6 6.8 0.34
5.34 3.4 NaN 1.1 
2 -4 -6 5 
NaN alanını haliyle double olarak okuyamayız. Atlamak için şöyle yaparız.
if (!(myFile>>x)) // Read might fail on "NaN"
{
    loadFile.clear(); // Reset error state
    loadFile.ignore(3); // This assumes we only fail on NaN.
}




21 Eylül 2015 Pazartesi

std::addressof

Giriş
std::addressof() C++11 ile yeni gelen bir metod. Kullanmak için <memory> dosyası include edilmeli.

Açıklaması şöyle. smart pointer'larda nesnenin adresini almak için kullanılır.Bu metoda hiç ihtiyacım olmadı. Ancak anladığım kadarıyla eğer & operatörü override edilmişse
bu metodu kullanarak nesnenin adresini alabiliriz.
& is often overloaded when building smart pointer classes, as it makes them easier to use: more often than not you want the bare managed pointer, not the address of the smart pointer object.

Neglecting the evolutionary backwater that was std::auto_ptr, smart pointer classes such as std::unique_ptr and std::shared_ptr have been introduced into the standard since C++11. std::addressof was introduced in that standard since taking the real address of an object is occasionally required.

Gerçekleştirim
GCC ve boost tarafından gerçekleştirimi şöyle.
reinterpret_cast<T*>(
    &const_cast<char&>(
        reinterpret_cast<const volatile char &>(object)))
Muhtemel gerçekleştirimi şöyle
template< class T >
T* addressof(T& arg) 
{
    return reinterpret_cast<T*>(
               &const_cast<char&>(
                  reinterpret_cast<const volatile char&>(arg)));
}
Örnek
Kullanımına dair bir örnek
#include <memory>
#include <iostream>

struct A {
    A* operator &() {return nullptr;}
};

int main () {
    A a;
    std::cout << &a << '\n';              // Prints 0
    std::cout << std::addressof(a);       // Prints a's actual address
}