5 Mart 2018 Pazartesi

User Defined Literal

Söz Dizimi
Söz dizimi şöyle.
Döndürülen tip + operator kelimesi + "" + literal eki + parametreler. 
Eğer istenirse döndürülen tipin başına constexpr de eklenebilir.

User Defined Literal Söz Dizimi Girdi Olarak Ne Alabilir
User defined Literal operator metodları sadece şu tipten parametreleri alabilir.
const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t
Parametreler arasında örneğin double yok. Dolayısıyla şu kod hata verir.
constexpr double operator "" _kg(double q)
{
   return q*1000;
}
long double için şöyle yapabiliriz.
long double operator""_a(long double);     
auto x = 0e1_a+0; // OK 
Bazı Literal Tipleri için Boşluk
Örnek
Literal E,e,p,P ise Saçma ama araya boşluk koymak gerekir. Şöyle yaparız.
long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);

auto x = 1.0_E+2.0;  // error
auto y = 1.0_a+2.0;  // OK
auto z = 1.0_E +2.0; // OK
auto w = 1_p+2;      // error
auto u = 1_p +2;     // OK

Örnek
Şöyle yaparız.
std::cout << 4_s .count();
//              ^ Space here!
Literal'dan Sonra Nokta
Şu kod derlenmez. Aslnda user defined literal foo yapısını döner, onun da bar metodunu çağırıyoruz diye düşünülebilir.
struct foo {
  int n;
  int bar() const { return n; }
};

constexpr foo operator ""_foo(unsigned long long test)
{
  return foo{ static_cast<int>(test) };
}

int main() {
  return 123_foo.bar();
}

Literal Örnekleri
const char*
Şöyle yaparız.
std::string operator"" _str(const char *s, std::size_t len) {
    return std::string(s, len);
}

auto str = "xxxxx"_str;
std::cout << str.size() << std::endl;    // works

std::cout << "xxxxx"_str.size() << std::endl;   // works
String
std::string içinde gömülü null kullanmak için şöyle yaparız.
std::string operator "" _s(const char* str, size_t n) 
{ 
    return std::string(str, n); 
}
Şöyle yaparız.
std::string my_string("a\0b"_s);
Şöyle yaparız.
auto my_string = "a\0b"_s;
unsigned long long
Örnek
Kendi int8_t literal ekimizi yazmak isteseydik şöyle yapardık
#include <cstdint>

constexpr std::int8_t operator "" _int8(unsigned long long v)
{
  return static_cast<std::int8_t> (v);
}
Örnek
Şöyle yaparız.
std::chrono::seconds operator"" _s(unsigned long long s) {
    return std::chrono::seconds(s);
}

auto sec = 4_s;
std::cout << sec.count() << std::endl;   // works

std::cout << (4_s).count() << std::endl;   // works
Birimler ve Ölçüler
Örneğin Kilo, Mega, Giga için harfler tanımlanabilir. Şöyle yaparız.
long long constexpr operator"" K (long double n) {
    return n * 1000;
}
long long constexpr operator"" M (long double n) {
    return n * 1000000;
}
long long constexpr operator"" G (long double n) {
    return n * 1000000000;
}
Daha sonra bu harfler sabitler ile kullanılabilir.
0.05M == 50000;
123.232K == 123232
1.000000001G == 1000000001

Hiç yorum yok:

Yorum Gönder