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:
- 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;
- 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);
- 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