foreach with Structs and Classes Solutions - D Programming Language
Description: D Programming Language
Keywords: D programming language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Discord (community-run)
  - Forums
  - IRC
  - Wiki
  - Issues
  - Contributing
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# foreach with Structs and Classes Solutions

#### `foreach` with Structs and Classes Dersi Problem Çözümleri

1. The step size must be stored alongside `begin` and `end`, and the element value must be increased by that step size:

       struct NumberRange {
           int begin;
           int end;
           int stepSize;

           int opApply(int delegate(ref int) dg) const {
               int result;

               for (int number = begin; number != end; number += stepSize) {
                   result = dg(number);

                   if (result) {
                       break;
                   }
               }

               return result;
           }
       }

       import std.stdio;

       void main() {
           foreach (element; NumberRange(0, 10, 2)) {
               write(element, ' ');
           }
       }

2.     import std.stdio;
       import std.string;

       class Student {
           string name;
           int id;

           this(string name, int id) {
               this.name = name;
               this.id = id;
           }

           override string toString() {
               return format("%s(%s)", name, id);
           }
       }

       class Teacher {
           string name;
           string subject;

           this(string name, string subject) {
               this.name = name;
               this.subject = subject;
           }

           override string toString() {
               return format("%s teacher %s", subject, name);
           }
       }

       class School {
       private:

           Student[] students;
           Teacher[] teachers;

       public:

           this(Student[] students, Teacher[] teachers) {
               this.students = students;
               this.teachers = teachers;
           }

           /* This opApply override will be called when the foreach
            * variable is a Student. */
           int opApply(int delegate(ref Student) dg) {
               int result;

               foreach (student; students) {
                   result = dg(student);

                   if (result) {
                       break;
                   }
               }

               return result;
           }

           /* Similarly, this opApply will be called when the foreach
            * variable is a Teacher. */
           int opApply(int delegate(ref Teacher) dg) {
               int result;

               foreach (teacher; teachers) {
                   result = dg(teacher);

                   if (result) {
                       break;
                   }
               }

               return result;
           }
       }

       void printIndented(T)(T value) {
           writeln("  ", value);
       }

       void main() {
           auto school = new School(
               [ new Student("Can", 1),
                 new Student("Canan", 10),
                 new Student("Cem", 42),
                 new Student("Cemile", 100) ],

               [ new Teacher("Nazmiye", "Math"),
                 new Teacher("Makbule", "Literature") ]);

           writeln("Student loop");
           foreach (Student student; school) {
               printIndented(student);
           }

           writeln("Teacher loop");
           foreach (Teacher teacher; school) {
               printIndented(teacher);
           }
       }

   The output:

       Student loop
         Can(1)
         Canan(10)
         Cem(42)
         Cemile(100)
       Teacher loop
         Math teacher Nazmiye
         Literature teacher Makbule

   As you can see, the implementations of both of the `opApply()` overrides are exactly the same, except the slice that they iterate on. To reduce code duplication, the common functionality can be moved to an implementation function template, which then gets called by the two `opApply()` overrides:

       class School {
       // ...

           int opApplyImpl(T)(T[] slice, int delegate(ref T) dg) {
               int result;

               foreach (element; slice) {
                   result = dg(element);

                   if (result) {
                       break;
                   }
               }

               return result;
           }

           int opApply(int delegate(ref Student) dg) {
               return opApplyImpl(students, dg);
           }

           int opApply(int delegate(ref Teacher) dg) {
               return opApplyImpl(teachers, dg);
           }
       }

Copyright © 1999-2026 by the D Language Foundation | Page generated by Ddoc on Wed Aug 19 13:28:52 2026