C++ の強力な能力の一端を担っているのがテンプレートでしょう.
しかし, 無理な拡張のせいか構文にも無理があったりする.
D 言語のテンプレートは C++ よりも洗練されており, 構文も整理されている.
template.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import std.stdio;
template Max(T){
T max(T lhs, T rhs){
if (lhs > rhs)
return lhs;
else
return rhs;
}
}
// alias Max!(int) IntMax;
void main(){
int r = Max!(int).max(10, 20);
/*
明示的なインスタンス化は, テンプレート名!(型名) と書く.
インスタンス化したテンプレートに別名を付けることもできる.
alias Max!(int) IntMax;
int r = IntMax.max(10, 20);
*/
writeln("Max!(int).max(10, 20) = ", r);
}
|
template.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./template
Max!(int).max(10, 20) = 20
template2.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import std.stdio;
T max(T)(T lhs, T rhs){
if (lhs > rhs)
return lhs;
else
return rhs;
}
void main(){
int r = max!(int)(10, 20);
// int r = max(10, 20);
/*
テンプレートパラメータ が一つだけのときは ! の後の () を省略できる
max!(int) は max!int と等価
関数テンプレートのテンプレート引数は, 与えられた引数の型から推論できるとき,
省略できる.
int r = max(10, 20);
*/
writeln("max!(int).max(10, 20) = ", r);
}
|
template2.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./template2
max!(int).max(10, 20) = 20
member_temp.d
1 2 3 4 5 6 7 8 9 10 11 12 13 | import std.stdio;
class SizeOf{
bool comp(T, U)(T lhs, U rhs){
return (lhs.sizeof == rhs.sizeof);
}
}
void main(){
SizeOf x = new SizeOf;
writeln( x. comp(1, 2) );
writeln( x. comp(1, '2') );
}
|
member_temp.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./member_temp
true
false
class_temp.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import std.stdio;
template Calc(T){
class Adder{
T add(T lhs, T rhs){
return lhs + rhs;
}
}
}
void main(){
Calc!(int).Adder x = new Calc!(int).Adder;
writeln( x.add(10, 20) );
/*
alias で別名を付ける場合
alias Calc!(int) IntCalc;
IntCalc.Adder x = new IntCalc.Adder;
*/
/*
クラスまで含めて別名をつけるなら
alias Calc!(double).Adder DoubleAdder;
DoubleAdder y = new DoubleAdder;
*/
}
|
class_temp.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./class_temp
30
関数テンプレートと同様の省略記法が使える.
class_temp2.d
1 2 3 4 5 6 7 8 9 10 11 12 13 | import std.stdio;
class Adder(T){
T add(T lhs, T rhs){
return lhs + rhs;
}
}
void main(){
Adder!(int) x = new Adder!(int);
// Adder!int x = new Adder!int; // このように, () を省略できる
writeln( x.add(10, 20) );
}
|
class_temp2.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./class_temp2
30
C++ でのテンプレートの特殊化と同様のことが D でもできる.
temp.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import std.stdio;
void f(T)(T t){
writeln(t);
}
void f(T:int)(T t){ // T が int のときはこちらの実装が使われる
writeln(t, " is int");
}
void main(){
f("hoge");
f(123);
}
|
temp.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./temp
hoge
123 is int