Giriş
std::pair ve std::tuple birbirlerine çok benziyorlar ancak std::tuple<A,B> ile std::pair<A,B> farklı tiplerdir.
std::pair ve std::tuple STL ile mecburen kullanılıyor çünkü algoritmaların genel (generic) olması gerekiyor. Kendi kodumda ise, std::pair ve std::tuple yerine daha anlamlı struct veya class'lar kullanmayı tercih ediyorum.
Şu satırı dahil ederiz.
std::pair ve std::tuple birbirlerine çok benziyorlar ancak std::tuple<A,B> ile std::pair<A,B> farklı tiplerdir.
std::pair ve std::tuple STL ile mecburen kullanılıyor çünkü algoritmaların genel (generic) olması gerekiyor. Kendi kodumda ise, std::pair ve std::tuple yerine daha anlamlı struct veya class'lar kullanmayı tercih ediyorum.
Şu satırı dahil ederiz.
#include <tuple>
constructor - brace initialization
İmzası şöyle. Direct constructor deniliyor.
Örnek
Elimizde şöyle bir kod olsun
constructor - std::make_tuple
Şöyle yaparız.
Constructor şu anda explicit tanımlı. C++17 ile sadece parametre explicit tanımlı class ise constructor explicit olacak hale gelecek. Dolayısıyla std::initializer_list ile kullanırken şu anda std::tuple şeklinde yazmak gerekiyor. Elimizde şöyle bir metod olsun.
Diğer
destructor sırası
Tuple içindeki elemanların hangi sıra ile yok edileceği belli değildir.
Kalıtım
tuple(const Types&... args );
Bir başka imzası şöyle. Aralarındaki farkı anlamadımtemplate< class... UTypes >
tuple( UTypes&&... args );
Örnek
Elimizde şöyle bir kod olsun
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
tuple şöyle ilklendirilir.ListNode node(0);
std::tuple<int, ListNode*> head{0, &node};
Yani brace initialization kullanılıyor.constructor - std::make_tuple
Şöyle yaparız.
std::tuple<int, float, double> t = std::make_tuple(1, (float)1.2, 5);
constructor explicit tanımlıdırConstructor şu anda explicit tanımlı. C++17 ile sadece parametre explicit tanımlı class ise constructor explicit olacak hale gelecek. Dolayısıyla std::initializer_list ile kullanırken şu anda std::tuple şeklinde yazmak gerekiyor. Elimizde şöyle bir metod olsun.
void ext( std::initializer_list<std::tuple<double, std::vector<double> >> myList )
{...}
Bu metodu şöyle çağırırız.ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );
operator ==
tuple içindeki elemanları teker teker karşılaştırır.
Örnek
Elimizde şöyle bir kod olsun
auto t1 = std::make_tuple("one", "two", "three");
auto t2 = std::make_tuple("one", "two", "three");
std::cout << "(t1 == t2) is " << std::boolalpha << (t1 == t2) << "\n";
std::cout << "(t1 != t2) is " << std::boolalpha << (t1 != t2) << "\n";
Çıktı olarak şunu alırız. İki tuple nesnesinin eşit olmamasının sebebi içlerindeki veri aynı olsa bile pointer'ların farklı bellek alanlarını göstermesi.
(t1 == t2) is false
(t1 != t2) is true
operator =
İmzası şöyle. std::tie ile kullanabilmeyi sağlar.template< class... UTypes >
tuple& operator=( const tuple<UTypes...>& other );
Diğer
destructor sırası
Tuple içindeki elemanların hangi sıra ile yok edileceği belli değildir.
Kalıtım
Bu niye gerekir bilmiyorum ama std::tuple'dan kalıtmak mümkün. Şöyle yaparız
struct MyIntTuple : std::tuple<int> {
using std::tuple<int>::tuple;
};
sizeofstd::tuple sizeof() işlemine sokulunca tam anlamıyla optimize edilmiyor. Açıklaması şöyle.
I've checked all major compilers, and sizeof(std::tuple<int, char, int, char>) is 16 for all of them. Presumably they just put elements in order into the tuple, so some space is wasted because of alignment.is_trivial
If tuple stored elements internally like: int, int, char, char, then its sizeof could be 12.
Is it possible for an implementation to do this, or is it forbidden by some rule in the standard?
std::tuple trival değildir. Şöyle yaparız
std::cout << std::is_trivial<std::tuple<int>>::value << std::endl;
Çıktı olarak şunu alırız.0
is_trivially_copyablestd::cout << std::is_trivially_copyable<std::tuple<int>>::value << std::endl;
Çıktı olarak şunu alırız.0
std::make_tupleusing namespace std;
int main(){
vector<tuple<int,int>> v;
for (int var = 0; var < 100000000; ++var) {
v.push_back(make_tuple(var, var));
}
}
make_tuple normalde hep value döndürür.int x, int y;
tuple<int,int> = make_tuple (x,y);
Ancak ref döndürmesini istersek std::ref ile kullanmak gerekir.int x, int y;
tuple<int&,int> = make_tuple (std::ref(x),y);
std::getstd::get yazısına taşıdım.
std::tie
Hiç yorum yok:
Yorum Gönder