Giriş
Şu satırı dahil ederiz.
1. Rust Dili
Benzer bir özellik Rust programlama dilinde var. O da bu özelliği Haskell'den almış deniliyor.
Örnek
Rust dilinde şöyle yaparız. old_enough() metodu sadece Years tipi ile çağrılabilir. i64 olan bir başka parametre ile çağrılamaz.
Örnek
Şu satırı dahil ederiz.
#include <boost/serialization/strong_typedef.hpp>
Bu macro niçin serialization altında bilmiyorum. Amacı mevcut bir tipten yepyeni bir tip tanımlayabilmek. Bu yepyeni tip, metod parametrelerinde kullanılarak daha type safe bir kod elde ediliyor.1. Rust Dili
Benzer bir özellik Rust programlama dilinde var. O da bu özelliği Haskell'den almış deniliyor.
Örnek
Rust dilinde şöyle yaparız. old_enough() metodu sadece Years tipi ile çağrılabilir. i64 olan bir başka parametre ile çağrılamaz.
struct Days(i64);
struct Years(i64);
fn old_enough(age: &Years) -> bool {
age.0 >= 18
}
2. typdef Kelimesi Farklı Tipler Yaratmak İçin YetersizdirÖrnek
İşe yaramadığını görmek için şöyle yaparız. Elimizde şöyle bir kod olsun.
3. using Kelimesi Farklı Tipler Yaratmak İçin Yetersizdir
Örnek
İşe yaramadığını görmek için şöyle yaparız
Eğer elimizdeki tip primitive ise enum kullanılabilir. Ancak primitive değilse bu çözüm işe yaramaz.
Örnek
Şöyle yaparız
Açıklaması şöyle. Template sınıfın ilk parametresini Tag yaparız.
Şöyle yaparız.
Ve nihayet bu macronun kullanımına bakalım.
typedef int TA;
typedef int TB;
std::variant<TA, TB> a(TA(1));
Bu kod içinde TA ve TB isminde iki farklı tip yaratılıyor gibi görünse de derleyici bunları farklı şeyler olarak düşünmeyebilir. Bu yüzden BOOST_STRONG_TYPEDEF kullanımına ihtiyacımız var.3. using Kelimesi Farklı Tipler Yaratmak İçin Yetersizdir
Örnek
İşe yaramadığını görmek için şöyle yaparız
typedef int Days;
using Years = int;
bool old_enough(Years age) {
return age >= 18;
}
4. Alternatif ÇözümlerEğer elimizdeki tip primitive ise enum kullanılabilir. Ancak primitive değilse bu çözüm işe yaramaz.
Örnek
Şöyle yaparız
enum class Days : int {};
enum class Years : int {};
bool old_enough(Years age) {
return static_cast<int>(age) >= 18;
}
5. Eğer Kendimiz Gerçekleştirmek İstersekAçıklaması şöyle. Template sınıfın ilk parametresini Tag yaparız.
...another common approach is making(/expanding) the Number class (template) a class template parameterized over type template tag parameter, such that specializations over the tag types results in strong typing.Örnek
Şöyle yaparız.
template<typename Tag, typename ValueType = int>
struct Number {
ValueType value;
// ... common number functionality.
};
using YearNumber = Number<struct NumberTag>;
using DayNumber = Number<struct DayTag>;
void takeYears(const YearNumber&) {}
void takeDays(const DayNumber&) {}
int main() {
YearNumber y{2020};
DayNumber d{5};
takeYears(y);
//takeDays(y); // error: candidate function not viable
takeDays(d);
//takeYears(d); // error: candidate function not viable
return 0;
}
6. BOOST_STRONG_TYPEDEF KullanımıVe nihayet bu macronun kullanımına bakalım.
Örnek
Şöyle yaparız. TIMER_ID ve PROCESS_ID string olmalarına rağmen == kodu derleme hatası verir.
Şöyle yaparız.
Elimizde şöyle bir typedef olsun
Şöyle yaparız. TIMER_ID ve PROCESS_ID string olmalarına rağmen == kodu derleme hatası verir.
BOOST_STRONG_TYPEDEF(std::string, TIMER_ID)
BOOST_STRONG_TYPEDEF(std::string, PROCESS_ID)
int main()
{
TIMER_ID t_id("Timer");
PROCESS_ID p_id("Process");
if (t_id == p_id)
std::cout << "They are equal!" << std::endl;
}
ÖrnekŞöyle yaparız.
BOOST_STRONG_TYPEDEF(int, X)
BOOST_STRONG_TYPEDEF(int, Y)
BOOST_STRONG_TYPEDEF(int, Width)
BOOST_STRONG_TYPEDEF(int, Height)
struct Rect {
Rect(X x, Y y, Width w, Height h);
};
// Usage:
Rect rect(X(10), Y(20), Width(800), Height(600));
ÖrnekElimizde şöyle bir typedef olsun
BOOST_STRONG_TYPEDEF(std::string, MY_ID)
Şöyle yaparız.std::vector<std::string> id_vec = ...;
std::set<MY_ID> ids;
for (auto const & id : id_vec)
{
ids.insert(MY_ID{id});
}