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;//避免继承非自己的子类,出现的错误.因而这样使用.
};
//这就是静态分发.是静态多态.动态多态要运行时查找.
模板的核心技术就是编译期多态.
参考在此
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现