C++ Dilinde Range Based For Loop
- Yusuf Hançar
- Nov 3, 2023
- 3 min read
Updated: May 20, 2024
C++ dilinde döngü kullanımına yeni bir başlık atılmıştır. Bu yeni özellik C++ dilinin sunduğu container ve kullanım senaryolarıdır. Dizi kullanımı olan yerlerde bilindiği üzere döngü ile içerisinde tutulan elemanlara erişim sağlanabilmektedir. Range based for loop; container içindeki tüm öğeler gibi bir range üzerinde çalışan standart for döngüsüne okunurluğu artırmaktadır.
Temel sentaks şu şekildedir : attr(optional) for (init-statement(optional)range-declaration : range-expression)
attr : Herhangi bir attributes optional olarak kullanılabilmektedir.
init statement : boş (null) bir ifade olarak geçilebilir yani boş bırakılabilir. (";")
range-declaration : Döngüde kullanılacak dizi veya veri yapısını temsilen kullanılmaktadır. Döngü içerisinde de bu temsil edecek isim kullanılarak döngü üzerinde işlem yapılmaktadır. C++17 itibari ile "structured binding declaration" kullanımı ve farklı şekillerde tanımlanabilir.
range-expression : Döngüde kullanılacak dizi veya veri yapısına verilen isim olarak kullanılmaktadır. "std::vector<string> svec;" buradaki svec range expression olarak döngüde kullanılacaktır. Bu expression braced-initialization ile de temsil edilebilmektedir. Aşağıda her biri örneklendirilecektir.
loop statement : Döngüde yapılan işlemlerdir.
Range expression ne olduğuna bağlı olarak döngüdeki begin() ve end() önem arz etmektedir. Çünkü bu döngü yapısının çalışabilmesi için kullanılan expression begin() ve end() tanımlarını içermek zorundadır. begin() container içindeki ilk elemanın konumunu yani iteratörünü döndürmektedir. end() ise container içindeki son elemandan sonraki konumu döndürmektedir. Bu sayede döngü ilk elemandan başlayarak begin() ile son elemana kadar end() ile giderek tamamlanabilmektedir.
Standart döngülerdeki gibi break ve continue kullanılara manipüle edilebilmektedir.
redeclaration problemi :
int main()
{
for (int idx : range-expression)
{
int idx;
cout << idx << ", ";
}
}
*****************************
AÇIKLAMA:
*****************************
CEVAP: error: redeclaration of ‘int idx’
*****************************
braced initialization ile kullanım :
int main()
{
for (auto idx : { 5, 6, 7 })
{
cout << idx << ", ";
}
}
*****************************
AÇIKLAMA: geçerli durumdur.
*****************************
CEVAP: 5 6 7
*****************************
int main()
{
int arr[] = { 5, 6, 7 };
for (auto idx : arr)
{
cout << idx << endl;
}
}
*****************************
AÇIKLAMA: geçerli durumdur.
*****************************
CEVAP:
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (const int& idx : ivec)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: access by const reference
*****************************
CEVAP:
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (auto idx : ivec)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: access by value, the type of idx is integer
*****************************
CEVAP:
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (auto&& idx : ivec)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: access by forwarding reference, the type of idx is int&
*****************************
CEVAP:
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
const auto& cv = ivec;
for (auto&& idx : cv)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: access by forwarding reference, the type of idx is const int&
*****************************
CEVAP:
*****************************
int main()
{
for (int cnt : { 0, 1, 2, 3, 4, 5 })
{
std::cout << cnt << ' ';
}
}
*****************************
AÇIKLAMA: the initializer may be a braced initializer list
*****************************
CEVAP:
*****************************
int main()
{
int arr[]{ 0, 1, 2, 3, 4, 5 };
for ([[maybe_unused]] int cnt : arr)
{
std::cout << 1 << ' ';
}
}
*****************************
AÇIKLAMA: the loop variable need to be used
*****************************
CEVAP:
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (auto cnt = ivec.size(); auto idx : ivec)
{
std::cout << --cnt + idx << ' ';
}
}
*****************************
AÇIKLAMA: the init statemenet (c++20)
*****************************
CEVAP: 5 5 5 5 5 5
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (typedef decltype(ivec)::value_type elem_t; elem_t idx : ivec)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: typedef declaration as init statement (c++20)
*****************************
CEVAP: 0 1 2 3 4 5
*****************************
int main()
{
std::vector<int> ivec{ 0, 1, 2, 3, 4, 5 };
for (using elem_t = decltype(ivec)::value_type; elem_t idx : ivec)
{
std::cout << idx << ' ';
}
}
*****************************
AÇIKLAMA: alias declaration as init statement (c++23)
*****************************
CEVAP: 0 1 2 3 4 5
*****************************

Comments