模板

来源:互联网 发布:网络安全工程师面试题 编辑:程序博客网 时间:2024/04/28 19:26
// Scoped Template
template Foo(T, U)
{
    class Bar {} // 类
    T foo(T t, U u) { return t; } // 函数
    T abc; // 变量
    alias T* TPtr; // 类型别名
}


alias Foo!(int, char) TFoo;


void demo1()
{
    TFoo.Bar b; // 自动初始化为null
    TFoo.foo(1, 'a');
    TFoo.abc = 3;
    TFoo.TPtr p; // 自动初始化为0x00


    auto i = 0;
}


// 类模板
class Abc(T)
{
    T _t;
}


alias Abc!(int) TAbc;


void demo2()
{
    TAbc abc; // 自动初始化为null


    auto i = 1;
}


// 多个模块中的模板
//module a;
//
//template Foo(T)
//{
//    T bar;
//}
//
//module b;
//
//import std.stdio;
//import a;
//
//void test()
//{
//    a.Foo!(int).bar = 3;
//    writeln("module b");
//}
//
//module c;
//
//import std.stdio;
//import a;
//
//alias a.Foo!(int).bar bar;
//
//void test()
//{
//    bar = 3;
//    writeln("module c");
//}
//
//module main;
//
//import std.stdio;
//import b, c;
//
//void main()
//{
//    b.test();
//    c.test();
//
//    getchar();
//}


class D
{
}


class C : D
{
}


interface I
{
}


class U : I
{
}


// 复杂的模板参数
class Foo( // 注意这个类模板与前面的Foo模板同名!!
          R, // R 可以是任何类型
          P: P*, // P 必须是指针类型
          T: int, // T 必须是 int 类型,即这个参数只能是int
          S: T*, // S 必须是指向 T 的指针,即这个参数只能是int*
          C: D, // C 必须属于类 D 或者是派生自 D
          U: I, // U 必须是这样一个类:实现了接口 I 的类
          f: float, // f必须是float类型
          float data, // 该参数要求是一个float类型的变量
          string str = "hello", // 该参数要求是一个字符串,默认值为 "hello"。注意有默认值的参数不能放中间
          alias A = D // A 是任何符号(包括模板符号),默认是 D。注意有默认值的参数不能放中间
          )
{
    void print()
    {
        writeln("in class template");
    }
}


void demo3()
{
    int a = 5;
    alias Foo!(D, byte*, int, int*, C, U, float, 1) TFoo;
    TFoo f = new TFoo();
    f.print();
}


int g(double d)
{
    return 1; 
}


alias double A; // 全局的


class B(T)
{
    alias int A; // 模板内部的
}


// 类模板的继承
class X(T) : B!(T)
{
    A a; // a 的类型是 int
    
    int T; // 正确,T 被重新声明为 int


    int foo()
    {
        char T; // 正确,T 被重新声明为 char
        return g(1); // 总是返回 2,调用的是后面那个精确匹配的函数
    }
};


void demo4()
{
    alias X!(int) TX;
    auto x = new TX();
    auto i = x.foo();
}


// 函数可以被向前引用
int g(int i) 
{
    return 2; 



// 模板实现递归
// 方法1
template factorial(int n)
{
    const factorial = n * factorial!(n - 1); // const是什么意思,为什么变量名必须与模板名相同才可以编译过?
}
template factorial(int n : 1) // 模板特化
{
    const factorial = 1;
}


// 方法2
template factorial0(int n)
{
    static if (n == 1) // static if?
    {
        const factorial0 = 1;
    }
    else
    {
        const factorial0 = n * factorial0!(n - 1);
    }
}


void demo5()
{
    writeln(factorial!(4)); // 输出 24
    writeln(factorial0!(4)); // 输出 24
}


template hash(string s, uint sofar = 0)
{
    static if (0 == s.length)
    {
        const hash = sofar;
    }
    else
    {
        const hash = hash!(s[1 .. $], sofar * 11 + s[0]);
    }
}


uint demo6()
{
    return hash!("i lovd lulu");
}




template decimalDigit(int n) // [3]
{
    const string decimalDigit = "0123456789"[n .. n + 1];
}
template itoa(long n)
{
    static if (n < 0)
    {
        const string itoa = "-" ~ itoa!(-n);
    }
    else static if (n < 10)
    {
        const string itoa = decimalDigit!(n);
    }
    else
    {
        const string itoa = itoa!(n / 10L) ~ decimalDigit!(n % 10L);
    }
}


string demo7()
{
    return itoa!(264); // 返回 "264"
}
原创粉丝点击