d的类型类.

 import std.stdio: writeln;
  import std.traits: hasStaticMember;
//特征
  template isNamed(alias T) {
      enum isNamed = hasStaticMember!(T, "secretlyIsNamed");
  }

  string greet(T)(T x) if (isNamed!T) {
      return "Hello " ~ x.name;
  }
  string greet(T)(T x) if (!isNamed!T) {
      return "Hello?";
  }

  struct World {
      static char[0] secretlyIsNamed;
  }

  string name(World x) { return "World"; }

  struct Alice { }
  string name(Alice x) { return "Alice"; }

  struct Bob {
      static char[0] secretlyIsNamed;
  }

  string name(Bob x) { return "Bob"; }

  void main() {
      writeln(greet(World()));
      writeln(greet(Alice()));
      writeln(greet(Bob()));
  }

输出:

  Hello World
  Hello?
  Hello Bob

另一个:

class Base {
        void doLotsOfStuff() {
                import std.stdio;
                writeln("I am doing lots of stuff.");
                writeln(childResult());
                writeln("cool");
        }

        int defaultValue() { return 5; }

        abstract int childResult();//抽象方法,不能去虚化
}

final class Child : Base {//final,最终可进行优化
        override int childResult() { return defaultValue() + 5; }
}

void workOnIt(T : Base)(T obj) {
        obj.doLotsOfStuff();
}//如果优化器在普通函数上失败了,试试模板优化.

void main() {
        import std.typecons;
        auto c = scoped!Child; // 栈分配
        Child obj = c; //取引用.

        workOnIt(obj);
}

更不虚:

// base is now a template too
class Base(T) {//成了模板类了.
	void doLotsOfStuff() {
		import core.stdc.stdio; // 用printf更干净的汇编
		printf("I am doing lots of stuff.\n");

                // 本转,允许静态分发
		printf("%d\n", (cast(T) this).childResult());//转为子.
		printf("cool\n");
	}

	int defaultValue() { return 5; }

	abstract int childResult();
}

// child inherits base specialized on itself, so it can see final
// down in the base as well as on the outside
final class Child : Base!(Child) {//所谓的循环模板方式,就是子类继承基类<子类>.这种方式
 	override int childResult() { return defaultValue() + 5; }
}//这是一种很神奇的思路.类 子:基!子{...},c++里面也很有用.

void workOnIt(T : Base!T)(T obj) {
	obj.doLotsOfStuff();
}

void main() {
	import std.typecons;
	auto c = scoped!Child; // on-stack store
	Child obj = c; // get the reference back out

	workOnIt(obj);
}

还可以更猛,用串插件和构,静态分发.

还可以

@Named struct World {}
@Named struct Bob {}

or mebbe

@implements!Named

只需要auto c = scoped!Class(args, to, ctor);.
这样:

abstract class Named {
    string name();
}

template isNamed(alias T) {
    import std.traits: hasUDA;

    enum isNamed = hasUDA!(T, Named);
    static if (isNamed) {
        static foreach (f; __traits(getVirtualFunctions, Named, "name")) {
            static assert(__traits(compiles, name(T())));
            //static assert(__traits(compiles, f(T())));
        }
    }
}

string greet(T)(T x) if (isNamed!T) {
    return "Hello " ~ x.name;
}
string greet(T)(T x) if (!isNamed!T) {
    return "Hello?";
}

@Named struct World {};
struct Alice {};
@Named struct Bob {};

string name(World x) { return "World"; }
string name(Alice x) { return "Alice"; }
string name(Bob x) { return "Bob"; }

void main() {
    import std.stdio: writeln;

    writeln(greet(World()));
    writeln(greet(Alice()));
    writeln(greet(Bob()));
}

学术名叫奇异递归:就是神奇的意思.

class Base(CRTP) {
    void process(T)(T t) { import std.stdio; writeln("default process ", T.stringof); }
    void process(T : int)(T t) { import std.stdio; writeln("specialized base int process"); }
    void someTraditionalMethod() {
         (cast(CRTP) this).process("my string");
         (cast(CRTP) this).process(0);
         (cast(CRTP) this).process([1]);
    }
}

class Child : Base!Child {
    void process(T : string)(T t) {
        import std.stdio; writeln("custom string process!");
    }
    void process(T)(T t) { super.process(t); } // still necessary to remind the compiler we do still want default fallback processing
}

void main() {
   auto child = new Child();
   child.someTraditionalMethod();
}

这个东西其实很爽,只是看你会用不会用.
crtp的正确打开方式:

template <typename T>
class Base
{
public:
    // ...
private:// import 
    Base(){};
    friend T;//避免继承非自己的子类,出现的错误.因而这样使用.
};

//这就是静态分发.是静态多态.动态多态要运行时查找.
模板的核心技术就是编译期多态.
参考在此

posted @   zjh6  阅读(13)  评论(0编辑  收藏  举报  
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示