Thread overview
Error: template instance does not match template declaration
Nov 17, 2021
Vitalii
Nov 17, 2021
Tejas
Nov 17, 2021
Tejas
Nov 17, 2021
Vitalii
Nov 17, 2021
Tejas
Nov 18, 2021
Vitalii
November 17, 2021

Hello! I am getting the following error:

inst.d(8): Error: template instance `Worker!(Mode.Inspect)` does not match template declaration `Worker(mode : Mode)

when compile next code:

enum Mode { Inspect, Execute }

class Worker(mode : Mode) {
	this() {}
}

void main() {
	auto W = Worker!(Mode.Inspect)();
}

Can anybody suggest to me what I do wrong?

November 17, 2021

On Wednesday, 17 November 2021 at 10:10:43 UTC, Vitalii wrote:

>

Hello! I am getting the following error:

inst.d(8): Error: template instance `Worker!(Mode.Inspect)` does not match template declaration `Worker(mode : Mode)

when compile next code:

enum Mode { Inspect, Execute }

class Worker(mode : Mode) {
	this() {}
}

void main() {
	auto W = Worker!(Mode.Inspect)();
}

Can anybody suggest to me what I do wrong?

enum Mode { Inspect, Execute }

class Worker(Mode /*no need for template specialization :) */a) {
	this() {}
}

void main() {
	auto W =  new/*Add new here, because this ais a class, not struct*/ Worker!(Mode.Inspect)();
}
November 17, 2021

On Wednesday, 17 November 2021 at 12:19:05 UTC, Tejas wrote:

>

On Wednesday, 17 November 2021 at 10:10:43 UTC, Vitalii wrote:

>

Hello! I am getting the following error:

inst.d(8): Error: template instance `Worker!(Mode.Inspect)` does not match template declaration `Worker(mode : Mode)

when compile next code:

enum Mode { Inspect, Execute }

class Worker(mode : Mode) {
	this() {}
}

void main() {
	auto W = Worker!(Mode.Inspect)();
}

Can anybody suggest to me what I do wrong?

enum Mode { Inspect, Execute }

class Worker(Mode /*no need for template specialization :) */a) {
	this() {}
}

void main() {
	auto W =  new/*Add new here, because this ais a class, not struct*/ Worker!(Mode.Inspect)();
}

Sorry for typo, I meant "is", not "ais" :(

November 17, 2021

Thank you for response, Tejas!

What I intended to do was make a class with only two states ("Inspect" - do some analysis, "Execute" - do some stuff). That's why I tried to use template specialization.

The following code compiles successfully, but return "fun with unknown" instead of "fun with Mode1", as I supposed. I think I missed some "static" thing in my code, but can't find any working examples. Any ideas?

import std.stdio : writeln;

enum Mode1;
enum Mode2;

class Worker(Mode) {
	this() {}

	void fun() {
		static if (is(typeof(Mode) == Mode1)) {
			writeln("fun with Mode1");
		}
		else static if (is(typeof(Mode) == Mode2)) {
			writeln("fun with Mode2");
		}
		else {
			writeln("fun with unknown");
		}
	}
}

void main() {
	auto W = new Worker!(Mode1)();
	W.fun();
}
November 17, 2021

On Wednesday, 17 November 2021 at 12:55:15 UTC, Vitalii wrote:

>

Thank you for response, Tejas!

What I intended to do was make a class with only two states ("Inspect" - do some analysis, "Execute" - do some stuff). That's why I tried to use template specialization.

The following code compiles successfully, but return "fun with unknown" instead of "fun with Mode1", as I supposed. I think I missed some "static" thing in my code, but can't find any working examples. Any ideas?

import std.stdio : writeln;

enum Mode1;
enum Mode2;

class Worker(Mode) {
	this() {}

	void fun() {
		static if (is(typeof(Mode) == Mode1)) {
			writeln("fun with Mode1");
		}
		else static if (is(typeof(Mode) == Mode2)) {
			writeln("fun with Mode2");
		}
		else {
			writeln("fun with unknown");
		}
	}
}

void main() {
	auto W = new Worker!(Mode1)();
	W.fun();
}

You're not using a normal template here, you're using a template that takes non-type parameters(basically you're using a template that takes variables as parameters rather than types)

import std.stdio : writeln;

enum Mode{
    Mode1,
    Mode2
}
//enum Mode2; You're creating two completely different enum types, why??? This a mistake or intentional?

class Worker(Mode m) {
	this() {}

	void fun() {
		static if (m == Mode.Mode1) /*You can't write Mode1 directly, use enumType.enumValue :(*/{
			writeln("fun with Mode1");
		}
		else static if (m == Mode.Mode2) {
			writeln("fun with Mode2");
		}
		else {
			writeln("fun with unknown");
		}
	}
}

void main() {
	auto W = new Worker!(Mode.Mode1)();
	W.fun();
}
November 17, 2021

On 11/17/21 7:55 AM, Vitalii wrote:

>

Thank you for response, Tejas!

What I intended to do was make a class with only two states ("Inspect" - do some analysis, "Execute" - do some stuff). That's why I tried to use template specialization.

Template parameters are of 3 types:

  1. A type parameter. This has a single symbol name, and represents a type provided by the caller.
enum Mode { a, b }
class Foo(Mode) {
  // inside here, `Mode` is a locally named type, not the enum
}
// usage
Foo!int;
  1. A template value. This is specified by using 2 names, the type of the value, and the name for the value to be used internally.
class Foo(Mode mode) {
   // NOW `Mode` is referring to the type of `mode`, and
   // `Mode` is the external type, not a local type
}

// usage
Foo!(Mode.a);
  1. An alias to a symbol, type, or value. This is specified using the keyword alias and then a name for the aliased symbol or value. This is probably the most versatile, and you can use this as a last resort if you aren't specifically interested in types or values, or you want a value that is of unknown type.
class Foo(alias mode) {
   // `mode` can be anything.
}

// usage
Foo!int;
Foo!(Mode.a);
Foo!5;
Foo!writeln;

Aside from those 3 basic template parameter mechanisms, there is specialization which provide a specialized template implementation if the arguments match or implicitly can convert to the specialization. I know there are some languages that use this syntax to specify the type of a parameter, but D does not. Note that alias specialization is not allowed.

enum Mode { a, b}
class Example(T : int) { pragma(msg, "specialized ", typeof(this)); }
class Example(T : Mode) { pragma(msg, "specialized2 ", typeof(this)); }
class Example(T) { pragma(msg, "unspecialized ", typeof(this)); }

Example!int a; // => "specialized Example!int"
Example!short b; // => "specialized Example!short"
Example!string c; // => "unspecialized Example!string"
Example!Mode d; // => "specialized2 Example!Mode"

class Example2(Mode mode : Mode.a) { pragma(msg, "specialized ", typeof(this)); }
class Example2(Mode mode) { pragma(msg, "unspecialized ", typeof(this)); }

Example2!(Mode.a) e; // specialized Example2!Mode.a
Example2!(Mode.b) f; // unspecialized Example2!Mode.b

I hope this helps you understand how to properly write these.

-Steve

November 18, 2021

On Wednesday, 17 November 2021 at 18:00:59 UTC, Steven Schveighoffer wrote:

>

On 11/17/21 7:55 AM, Vitalii wrote:

>

[...]

Template parameters are of 3 types:

  1. A type parameter. This has a single symbol name, and represents a type provided by the caller.

[...]

Steve, thank you very much for the detailed answer! Much has become clearer.