是否可以在编译时将prod_list = []
prod1 = Product(3, 3, 3)
prod_list.append(prod1)
prod2 = Product(3, 3, 2)
prod_list.append(prod2)
prod3 = Product(3, 3, 3)
print prod3 in prod_list
True
prod3 = Product(3, 3, 5)
print prod3 in prod_list
False
强制转换为Foo
?
以下是更多背景信息:
ubyte[size]
问题是我无法在编译时将struct Algebraic(Types...)
if(Types.length < char.max - 1){
import std.traits: Largest;
import std.meta: IndexOf;
static immutable maxSize = Largest!(Types).sizeof;
this(T)(in T t)
if(IndexOf!(T, Types) !is -1){
type = IndexOf!(T, Types);
data = *cast(ubyte[maxSize]*)&t;
}
void opAssign(T)(in T t)
if(IndexOf!(T, Types) !is -1){
type = IndexOf!(T, Types);
data = *cast(ubyte[maxSize]*)&t;
}
inout(T*) peek(T)() inout{
if(type is IndexOf!(T, Types)){
return cast(inout(T*))&data;
}
return null;
}
private:
ubyte[maxSize] data;
char type = char.max;
}
struct Branch{
int index;
int left;
int right;
}
struct Leaf{
int index;
}
struct Foo{
alias Node = Algebraic!(Branch, Leaf);
Node n = Branch(1,2,3);
//Error: cannot convert &const(Branch) to ubyte[12]* at compile time
}
强制转换为Branch
。
答案 0 :(得分:4)
我不知道任何“干净”的方法(利用ABI的编译器知识),因为CTFE在防止重新解释方面非常保守。但是,如果这是一个阻塞程序,可以手动构建字节数组,使用结构ABI非常简单:
import std.traits;
ubyte[T.sizeof] reinterpret (T) ( T x )
if (!hasIndirections!T)
{
typeof(return) result;
static if (is(T == struct))
{
size_t offset = 0;
foreach (ref field; x.tupleof)
{
result[offset .. offset + field.sizeof] = reinterpret(field);
offset += field.sizeof;
}
}
else static if (is(T : ulong))
{
for (auto i = 0; i < x.sizeof; ++i)
result[i] = cast(ubyte) (x >> 8*i);
}
else
{
// handle floating types, arrays etc.
}
return result;
}
struct S
{
int x, y;
}
static immutable bytes = reinterpret(S(42, 42));
pragma(msg, bytes);
此方法存在一个巨大的限制:您需要手动调整到适当的ABI。像endianess这样的东西是微不足道的,但正确处理字段对齐可能是一种痛苦(我甚至不想在这个代码片段中这样做)。