21 Mayıs 2018 Pazartesi

std::wstring Sınıfı

Giriş
std::wstring wchar_t tipini kullanır. Bu tipin büyüklüğü Windows'ta 16 bit, Mac OS ta 32 bit tip.

Dolayısıyla  std::wstring portable kodlara sebep olmuyor. Açıklaması şöyle.
Do not use std::wstring if you care about portability (wchar_t is only 16 bits on Windows); use std::u32string instead (aka std::basic_string<char32_t>).
tchar - Windows
Windows'ta hem Unicode hem de MCBS çalışmak istersek tchar kullanmak gerekir. Şu satırı dahil ederiz.
#include <tchar.h>
Bu durumda TCHAR tipini kullanabiliriz.
TCHAR> c = ...
_T("...") macrosunu kullanabilir.
_T("MTS");
LPCTSTR yapısını kullanabiliriz.
LPCTSTR p = ...
Constructor
Windows'ta şöyle yaparız.
std::wstring str = L"MTS";
Windows'ta std::wstring ile std::basic_string<WCHAR> aynı şeydir. Şöyle yaparız.
std::basic_string<WCHAR> str = L"MTS";
Windows'ta tchar kullanmak istersek şöyle yaparız.
std::basic_string<TCHAR> str = _T("MTS");
c_str metodu
Windows'ta şöyle yaparız.
LPCWSTR b = str.c_str();
Windows'ta tchar kullanmak istersek şöyle yaparız.
LPCTSTR b = str.c_str();
Diğer - MultiByteToWideChar
Windows'ta şöyle yapabiliriz.
std::wstring A2T(const std::string& str)
{
  if (str.empty())
    return std::wstring();
  int sz = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);

  std::wstring res(sz - 1, 0);
  //                  ^^^ count to "remove" the NULL
  MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &res[0], res.size());
  //                                       ^^^ use actual sizes
  return res;
}


15 Mayıs 2018 Salı

std:try_lock metodu

Giriş
İmzası şöyle. Eğer kilitlerden herhangi birisini alamazsa aldığı kilitleri serbest bırakır ve false döner.
int try_lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn);

C++ ve noexcept

noexcept operator
Açıklaması şöyle.
Having the noexcept(x) specifier in a function declaration means that the function is non-throwing if and only if x evaluates to true.
Metodun exception atıp atmadığını döndürür. Şöyle yaparız.
struct X
{
    ~X() { };
};

int main()
{
    X x;

 
    static_assert(noexcept(x.~X()), "Ouch!");
}
noexcept ve default argument
Default argument çağıran tarafından yaratıldığı için şöyle yaparız.
void test(const Item& item = Item()) noexcept {
   ...
}
noexcept(x)
Açıklaması şöyle.
Having the noexcept(x) specifier in a function declaration means that the function is non-throwing if and only if x evaluates to true.
Örnek
Şöyle yaparız.
template <class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
noexcept (true) - exception fırlatılmaz
Bazı metodların imzasında noexcept(true) kelimesi görülür. Bu kelime metodun exception fırlatmayacağını garanti ettiği anlamına gelir.
Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph. An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing noexcept-specification.
Eğer bir metodu kalıtır ve imzadaki noexcept'i kullanmayı ihmal edersek şöyle bir uyarı alırız.
looser throw specifier for ‘virtual ...’
Açıklaması şöyle.
C++ used to have some form of checked exceptions, you may have noticed it has been deprecated and simplified toward a basic noexcept(<bool>) instead: either a function is declared to possibly throw, or it's declared never to.
noexcept (false)
noexcept (true)'nun tersi noexcept(false) gibi düşünülüyor ancak bu şekilde kullansak ta metodun exception fırlatıp fırlatmamasıyla ilgili bir şey belirtmiş olmayız.
A function with no exception-specification or with an exception-specification of the form noexcept(constant-expression) where the constant-expression yields false allows all exceptions. An exception-specification is non-throwing if it is of the form throw(), noexcept, or noexcept(constant-expression) where the constant-expression yields true. A function with a non-throwing exception-specification does not allow any exceptions.


7 Mayıs 2018 Pazartesi

C++11 ile Constructor Inheritance

Giriş
using kelimesi birçok faklı amaç için kullanılabiliyor. C++11 ile gelen yeniliklerden bir tanesi ata sınıftaki erişimimiz olmayan metodları erişilebilir hale getirmesi. Bu konu için using kelimesi yazısına bakabilirsiniz.

Bir diğer kullanım yeri ise ata sınıftaki constructor'ı kendi sınıfımızın içine alması.

Constructor inheritance Java, C# gibi dillerde bile olmayan bir özellik.  Açıklaması şöyle
If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using Base::Base;), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.
Eğer aynı imzalı constructor sağlarsak ata sınıftaki constructor gizlenir. Açıklaması şöyle. Dolayısıyla bizi bu dertten de kurtarıyor.
As with using-declarations for any other non-static member functions, if an inherited constructor matches the signature of one of the constructors of Derived, it is hidden from lookup by the version found in Derived.
Örnek
Eskiden ata sınıfın bir constructor metodunu kalıtan sınıfta da yazmak gerekiyordu.
class Base {
public:
  int i;
  Base(int x): i(x) {}
};

class Derived : private Base {
public:
  Derived(int x) : Base(x) {}
};
Şimdi artık using Base::Base yapmamız yeterli. Şöyle yaparız.
class Base {
public:
  int i;
  Base(int x): i(x) {}
};

class Derived : private Base {
public:
    using Base::Base;
};
Örnek
Şöyle yaparız.
class Foo : public Base {
public:
  using Base::Base;

  // My subclass specific code
};
Ata Sınıfın Constructor Erişimini Değiştirmek
Ata sınıfın constructor metodu public ise bunu sonradan private yapmak mümkün değil.

Örnek
Elimizde şöyle bir kod olsun.  Ata sınıfın constructor metodu private yapılamaz.
#include <vector>

template<typename T>
class Vec : std::vector<T>
{
private:
    using std::vector<T>::vector;       // Works, even if private. Why?
public:
    using std::vector<T>::operator[];   // must be public
};

int main(){
    Vec<int> vec = {2, 2};
    auto test = vec[1];
}
Parametrelere Erişim 
Ata sınıfın constructor metoduna geçilen parametrelere erişim artık mümkün değil. Elimizde Base sınıfı olsun ve bu sınıfın int alan bir constructor metodu olsun.
class Base {
  int y;
public:
  Base (int a) : y(a)  {}
};
Kalıtan sınıfın int a parametresine erişimi artık mümkün değil.
class Derived : public Base
{
    public:
    using Base::Base;
    float z {a}; //Bu olmuyor
};
Ancak şöyle yapılabilir.
class B : public A
{
  int z {y}; //Bu olur
public:
  using A::A;
};
Her Türlü Constructor Inherit Edilebilir mi ?
Constructor inheritance, parameterless constructor veya copy constructor için kullanılamaz.
For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.
Dolayısıyla aşağıdaki kod derlenmez
class C {
public:
    C(int) {}
    C(const C&) {}
    C() {}
};  

class D : public C { 
public:
    using C::C;
};  

int main() {
    C c;
    D d_from_c(c); // does not compile, copy ctor is not inherited
    D d_from_int(1); // compiles, C(int) is inherited
}