我有像
这样的结构
struct RGBA (T) {/* ... */}
struct BMPFile (DataT) if (is(DataT == RGBA)) {/* ... */}
但is(DataT == RGBA)
无效,因为DataT是一种类型而RGBA是一种模板。相反,我需要检查类型是否是模板的实例化,以便声明file
类似
BMPFile!(RGBA!ushort) file;
在评论中@FeepingCreature显示
struct RGBA(T) {
alias void isRGBAStruct;
}
struct BMPFile (DataT) if (is(DataT.isRGBAStruct)) {}
虽然为了工作但我没有alias void isRGBAStruct
的提示,这似乎是一个黑客。希望std.traits能够涵盖这一点。
答案 0 :(得分:6)
我认为你正试图过度具体。我处理这个问题的方法是允许DataT
的任何类型,只要它实现我需要的任何接口。
我认为,在D2标准库中完成此操作的方法是使用IsIntegral
这样的模板来测试类型的各种属性。
例如,假设您对DataT
的要求是您可以finangle
。你可以写:
template IsAppropriate(DataT)
{
enum IsAppropriate = is(typeof( { DataT d; d.finangle(); }() ));
}
带上一点盐:我没有测试过,但我相信这是基本模式。如果你不熟悉上面的内容,它正在做的是检查给定的匿名函数是否编译;它只能在finangle
DataT
。{/ p> {{1}}时进行编译
答案 1 :(得分:2)
这完全来自记忆,所以请稍等一些。
首先,那些结构需要实体,你应该从中得到解析错误。其次,BMPFile
上的模板约束不起作用,因为它试图比较RGBA!ushort
(一种类型)和RGBA
(一种模板),它们是不同类型的东西。最后我检查了(并且已经有一段时间了)没有干净的方法来检查类型是否是给定模板的实例化。
答案 2 :(得分:2)
一旦模板被实例化,它就是它自己的野兽。如果您有
等结构struct RGBA(T)
{
}
您不能直接测试该结构的特定实例化是否是该结构的瞬时。您可以测试像is(RGBA!int == RGBA!int)
或者是(RGBA!T == RGBA!int)`(如果你有T),但没有办法询问泛型类型是否是RGBA的实例化。
原因主要是因为RGBA 不是类型。它是一种类型的模板。在实例化模板之前不存在任何类型,并且模板的实例化与模板的任何其他瞬时没有任何关系。 RGBA!int与RGBA!float无关。由于模板约束和模板特化等,这两种类型可能完全不同。 e.g。
struct RGBA(T : int)
{
float a;
double b;
bool[] c;
}
struct RGBA(T : float)
{
@property int w() const pure nothrow
{
return 2;
}
}
现在,如果你愿意稍微限制自己,你可以玩游戏。诀窍是你需要一种方法来获得用于实例化RGBA的T.所以,这样的事情会起作用:
import std.traits;
struct RGBA(T)
{
}
struct BMPFile(DataT, T)
if(is(DataT == RGBA!T) &&
IsIntegral!T)
{
}
现在,这有一个限制,即T是一个整数类型,可能是你想要的,也可能不是。 isFloatingPoint!()
is(T == bool)
和std.traits
中的一些函数以及__traits
中的特征都可以正常工作。因此,如果您对T的含义有所了解,可以添加适当的约束来检查T的类型。
现在,如果你做了类似
的事情struct BMPFile(DataT, T)
if(is(DataT == RGBA!T))
然后总是第二次给出类型,这也会起作用:BMPFile(RGBA!int, int)
(虽然我猜你真的不想这样做)。
另一种选择是,如果你知道RGBA上有一个返回T
或者T
的函数,你可以测试DataT上是否存在该函数,并使用特征来获取类型。 e.g。
import std.traits;
struct RGBA(T)
{
T func() { return T.init;}
}
struct BMPFile(DataT, T = ReturnType!(DataT.func))
if(is(DataT == RGBA!T))
{
}
然而,当你传递一些没有func
函数的东西时,它的错误消息会变得非常难看,并且如果从RGBA实例化的类型以外的类型设置为匹配模板,那么'将尝试并实例化它,这可能会或可能不会工作,但在任何一种情况下可能都不是你想要的。
所以,它归结为目前没有任何方法可以直接做你想做的事情,但是如果你玩一些游戏,你可以得到一些有效的东西。本质上,它归结为找到一种方法来定义模板,以便您可以访问用于实例化第一个模板的参数(在本例中为RGBA
),以便您可以测试类型({{ 1}})给第二个模板(DataT
)是该类型的实例化(BMPFile
)。如果你能得到RGBA!T
,那么你可以测试T
。