泛型类型的签名约束

2024-01-20

struct S(int a, int b) { }

void fun(T)(T t) { }

I want fun跟...共事S仅有的。签名约束是什么样的?

我做不到fun的成员S, 与void fun(T)(T t) if(is(T : S)) { } I get Error: struct t1.S(int a,int b) is used as a type


S不是一个类型。它是一个类型的模板。S!(5, 4)是一种类型。很可能不同的实例S产生完全地不同的代码,所以定义S!(5, 4)可能完全地不同于S!(2, 5)。例如,S可能

struct S(int a, int b)
{
    static if(a > 3)
        string foo;

    static if(b == 4)
        int boz = 17;
    else
        float boz = 2.1;
}

请注意,成员变量的数量和类型不同,因此您不能真正使用S!(5, 4)代替一个S!(2, 5)。它们也可能是名为的结构U and V对于它们之间真正存在的所有关系来说,它们根本没有被模板化。

现在,特定模板的不同实例在 API 方面通常是相似的(或者它们可能不会使用相同的模板来完成),但从编译器的角度来看,它们彼此没有关系。因此,处理它的正常方法是纯粹对类型的 API 使用约束,而不是对其名称或实例化的模板使用约束。

所以,如果你期望S具有以下功能foo, bar, and foozle,而你想要你的fun要使用这些函数,那么您将构造一个约束来测试赋予的类型fun具有这些功能并且它们按预期工作。例如

void fun(T)(T t)
    if(is({ auto a = t.foo(); t.bar(a); int i = t.foozle("hello", 22);}))
{}

然后任何具有称为函数的类型foo它返回一个值,一个名为的函数bar它可能会或可能不会返回一个值,并且其结果是foo,以及一个名为foozle这需要一个string and an int并返回一个int将编译fun. So, fun比您坚持只进行实例化要灵活得多S。在大多数情况下,此类约束被分成单独的同名模板(例如isForwardRange or isDynamicArray)而不是将原始代码放入is expression这样它们就可以重用(并且更加用户友好),但是类似的表达式是此类同名模板在内部使用的。

现在,如果你really坚持约束fun这样它只适用于实例化S,那么我知道有两个选项。

1.添加某种声明S总是有,而且你不希望任何其他类型有。例如

struct S(int a, int b)
{
    enum isS = true;
}

void fun(T)(T t)
    if(is(typeof(T.isS)))
{}

请注意,声明的实际值并不重要(其类型也不重要)。这是一个简单的事实,即您正在测试它的存在。

2.更优雅(但不太明显的解决方案)是这样做:

struct S(int a, int b)
{
}

void fun(T)(T t)
    if(is(T u : S!(i, j), int i, int j))
{}

is表达式 http://dlang.org/expression.html#IsExpression一旦变得非常复杂,就有接近巫毒的倾向,但带逗号的版本正是您所需要的。这T u是您正在测试的类型和标识符;这: S!(i, j)给出您想要的模板专业化T是一个实例;剩下的就是TemplateParameterList声明在左侧的内容中使用但之前尚未声明的符号 - 在这种情况下,i and j.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

泛型类型的签名约束 的相关文章

  • Python %d,%s,%f

    当你看到输出语句存在 d s f等百分号的时候 就接触到python 字符串格式化输出相关知识 Python 支持字符串格式化输出 尽管这样可能遇到非常复杂的表达式 但最基本的是用法就是将一个值插入到一个有字符串格式符 s的字符串中 如 例
  • GDC 和 DMD 之间的选择

    我是 D 编程新手 选择 DMD 2 061 或 GDC 4 6 4 7 或 4 8 快照 的优缺点是什么 我应该选择哪个 GDC 版本 我已经成功构建了 GCC 4 8 和 GDC 4 8 的最新快照 并且它编译了一个 hello wor
  • 如何以完美的精度将字符串转换为浮点数?

    我正在尝试用 D 编程语言编写一个函数来替换对 C 的 strtold 的调用 理由 要使用 D 中的 strtold 您必须将 D 字符串转换为 C 字符串 这是低效的 而且 strtold 无法在编译时执行 我已经提出了一个大部分有效的
  • ANTLR 中的浮点文字和范围参数

    我正在开发 D 语言的解析器 当我尝试添加 切片 运算符规则时遇到了麻烦 你可以找到它的ANTLR语法here 基本上问题是 如果词法分析器遇到这样的字符串 1 2 它就会完全丢失 并且最终成为单个浮点值 因此像 a 10 这样的字符串的后
  • D 中的优雅运算符重载

    有一段时间我对 D 运算符重载的方向感到困惑 但现在我意识到这是一个漂亮的系统 如果它只适用于核心类型 int float 等 考虑以下代码 struct Vector float X Y void opOpAssign string op
  • ptrdiff_t 太小?

    我一直想知道 不是吗ptrdiff t应该能够保存任意两个指针的差异根据定义 为什么当两个指针距离太远时会失败 我不是指任何特定的语言 我指的是具有这种类型的所有语言 例如 用地址减去指针1从带有地址的字节指针0xFFFFFFFF当你有 3
  • 在 OS X 上初始化 D 运行时

    编辑 这似乎是一个长期存在的问题 没有迫在眉睫的解决方案 http d puremagic com issues show bug cgi id 8133 http d puremagic com issues show bug cgi i
  • D 语言中的并行迭代器

    我正在尝试用 D 语言实现一个图数据结构 它支持节点和边集上的并行迭代 alias ulong index alias index node alias ulong count class Graph index z max node in
  • 与平台无关的文件锁定?

    我正在进行一项计算量非常大的科学工作 时不时地会得出结果 这项工作基本上就是多次模拟同一件事 因此它被分配到使用不同操作系统的多台计算机上 我想将所有这些实例的输出定向到同一个文件 因为所有计算机都可以通过 NFS Samba 查看相同的文
  • SDL 窗口似乎被操作系统错误地标记为“无响应”

    我有一个通过 Derelict 3 访问的 SDL2 窗口 它应该是黑白频闪 不是因为我讨厌癫痫病患者 而且它成功地做到了这一点 然而 在一段时间后 Ubuntu 13 10 将窗口标记为 无响应 将其变灰 并使频闪效果变暗 这非常令人恼火
  • 处理传入消息的最佳方式是什么?

    我正在为一个在线游戏编写一个服务器 最终应该能够处理 1 000 2 000 个客户端 我发现做到这一点的三种方法基本上是 1 个线程 连接 阻塞 制作客户端列表 并循环它们 非阻塞 选择 基本上是一次针对所有客户端的阻塞语句 并带有可选超
  • D 退出语句

    D有没有退出语句 类似于java python c c 中的退出语句 哪一个会 令人震惊 退出程序的执行 就像是exit 如果你想exit 然后使用Cexit功能 import core stdc stdlib void main exit
  • D的语法真的是上下文无关的吗?

    几个月前我在 D 新闻组上发布了这个问题 但由于某种原因 答案从未真正说服我 所以我想我应该在这里问 D 的语法显然是上下文无关的 http www digitalmars com d 2 0 template comparison htm
  • 在 D 中制作结构体的堆副本

    如何创建堆栈上结构的垃圾收集副本 来自 C 背景 我的第一个猜测是像下面这样的复制构造函数 但它对于 D 来说似乎不太惯用 而且我在我看过的任何 D 项目中都没有看到过这样的复制构造函数 struct Foo immutable int b
  • D 中是否有相当于 C++ 的 Future/Promise ?

    D 世界中是否存在 C 世界中的未来 承诺等价物 当然有标准并行度 http dlang org phobos std parallelism html但它并不完全具有承诺 未来组合的功能 没有相当于获取未来或设置结果或异常的功能 您也不能
  • 最有效的便携式溢出检测? [复制]

    这个问题在这里已经有答案了 与 C C 和 D 等金属语言类似 检测无符号 64 位溢出的最有效 合理可移植的方式是什么 即不使用汇编程序 尽管您可能假设二进制补码算术和环绕行为 乘法中的整数 通过将无符号类型可表示的最大值除以被乘数之一
  • mpi.h:使用未定义的类型?

    我正在尝试将 OpenMPI 的 mpi h 的重要部分翻译为 D 编程语言 以便我可以从 D 调用它 HTOD 根本不起作用 我无法理解以下代码段 typedef struct ompi communicator t MPI Comm O
  • 二进制文件 I/O

    如何用D语言读写二进制文件 在 C 语言中是 FILE fp fopen home peu Desktop bla bin wb char x 4 RIFF fwrite x sizeof char 4 fp 我在 D 找到了 rawWri
  • D 中的特征可以用于类型类吗?

    我是 D 新手 我正在寻找一种使用类似 Haskell 的类型类进行编程的好方法 例如D 中的函子 幺半群等 Tango 或 Phobos 中是否实现了类似的功能 我听说过可以对某些属性进行编译时类型检查的特征 它们可以用于类型类吗 我尝试
  • D 动态数组初始化、stride和索引操作

    抱歉 这成为了有关数组的三重问题 我认为 动态 数组在 D 中确实很强大 但以下问题已经困扰我一段时间了 在 C 中 我可以轻松地分配具有指定值的数组 但在 D 中 我还没有找到这样做的方法 当然下面的内容是没有问题的 int a new

随机推荐