Thread overview
Debug help - foreach opApply overload School example: Programming in D
2 days ago
Brother Bill
2 days ago
Dejan Lekic
2 days ago
Brother Bill
2 days ago

Page 496 of Programming in D

Going in circles. Please correct so it compiles and works.
An explanation would be helpful also.

Error Message

c:\dev\D\71 - 80\c73_2d_School_Student_Teacher\source\app.d(23): Error: cannot implicitly convert expression `this.students[cast(ulong)i]` of type `const(Student)` to `app.Student`
            Student student = students[i];
                                      ^

source/app.d

import std.stdio;

void main() {
	auto school = new School;

	foreach (Student student; school) {

	}

	foreach (Teacher teacher; school) {

	}
}

class School {
	Student[] students;
	Teacher[] teachers;

	int opApply(int delegate(ref Student) dg) const {
		int result = 0;

		for (int i = 0; i < students.length; ++i) {
			Student student = students[i];
			result = dg(student);
			if (result) break;
		}

		return result;
	}

	int opApply(int delegate(ref Teacher) dg) const {
		int result = 0;

		return result;
	}
}

class Student {
	string name;
}

class Teacher {
	string name;
}
2 days ago

On Monday, 18 August 2025 at 13:32:57 UTC, Brother Bill wrote:

>

Page 496 of Programming in D

Going in circles. Please correct so it compiles and works.
An explanation would be helpful also.

Ali's book have a section about const member qualifier - "51.5 const member functions", but I think it should have more examples for absolute beginners. The online D reference has a better example here: https://dlang.org/spec/declaration.html#methods-returning-qualified . This example shows what happens when method is declared const (see how struct member gets const qualifier). Pay attention to the comment // error, cannot convert const(int)* to int* . This is exactly why you have the similar error. if Ali's reading this - it would be good to include an example showing this problem. To be fair, his book does not have this exact code - it was written by you.

So, to fix your error, you can remove the "const" method qualifier from opApply, or cast the const away from the member when you use it.

2 days ago

On Monday, 18 August 2025 at 17:58:54 UTC, Dejan Lekic wrote:

>

So, to fix your error, you can remove the "const" method qualifier from opApply, or cast the const away from the member when you use it.

Thanks for the tip. It just needed more 'const' keywords sprinkled in here and there.

Here is a working example:

STUDENTS
Bob
Carol
Ted
Alice

TEACHERS
Mr. Smith
Dr. Kildare
Albert Einstein

source/app.d

import std.stdio;

void main() {
	auto school = new School;

	school.addStudent("Bob");
	school.addStudent("Carol");
	school.addStudent("Ted");
	school.addStudent("Alice");

	school.addTeacher("Mr. Smith");
	school.addTeacher("Dr. Kildare");
	school.addTeacher("Albert Einstein");

	writeln("STUDENTS");
	foreach (const Student student; school) {
		writeln(student.name);
	}
	writeln;

	writeln("TEACHERS");
	foreach (const Teacher teacher; school) {
		writeln(teacher.name);
	}
}

class School {
	Student[] students;
	Teacher[] teachers;

	int opApply(int delegate(ref const Student) dg) const {
		int result = 0;

		for (int i = 0; i < students.length; ++i) {
			const Student student = students[i];
			result = dg(student);
			if (result)
				break;
		}

		return result;
	}

	int opApply(int delegate(const ref Teacher) dg) const {
		int result = 0;

		for (int i = 0; i < teachers.length; ++i) {
			const Teacher teacher = teachers[i];
			result = dg(teacher);
			if (result)
				break;
		}
		return result;
	}

	void addStudent(string studentName) {
		students ~= new Student(studentName);
	}

	void addTeacher(string teacherName) {
		teachers ~= new Teacher(teacherName);
	}
}

class Student {
	string name;

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

class Teacher {
	string name;

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